blob: 03ccd6c949ce87eafde5e0760383586691b7148f [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;
Jeya R85f57d32020-05-26 18:17:26 +0530729 if (fl && !(map->flags == ADSP_MMAP_HEAP_ADDR ||
730 map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR)) {
731 cid = fl->cid;
732 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
733 if (err) {
734 err = -ECHRNG;
735 pr_err("adsprpc: ERROR:%s, Invalid channel id: %d, err:%d",
736 __func__, cid, err);
737 return;
738 }
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530739 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530740 if (map->flags == ADSP_MMAP_HEAP_ADDR ||
741 map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
742 spin_lock(&me->hlock);
743 map->refs--;
744 if (!map->refs)
745 hlist_del_init(&map->hn);
746 spin_unlock(&me->hlock);
c_mtharu7bd6a422017-10-17 18:15:37 +0530747 if (map->refs > 0)
748 return;
c_mtharue1a5ce12017-10-13 20:47:09 +0530749 } else {
c_mtharue1a5ce12017-10-13 20:47:09 +0530750 map->refs--;
751 if (!map->refs)
752 hlist_del_init(&map->hn);
c_mtharu7bd6a422017-10-17 18:15:37 +0530753 if (map->refs > 0 && !flags)
754 return;
c_mtharue1a5ce12017-10-13 20:47:09 +0530755 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530756 if (map->flags == ADSP_MMAP_HEAP_ADDR ||
757 map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700758
c_mtharue1a5ce12017-10-13 20:47:09 +0530759 if (me->dev == NULL) {
760 pr_err("failed to free remote heap allocation\n");
761 return;
762 }
763 if (map->phys) {
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +0530764 unsigned long dma_attrs = DMA_ATTR_SKIP_ZEROING |
765 DMA_ATTR_NO_KERNEL_MAPPING;
Tharun Kumar Merugu48d5ff32018-04-16 19:24:16 +0530766 dma_free_attrs(me->dev, map->size, (void *)map->va,
767 (dma_addr_t)map->phys, dma_attrs);
c_mtharue1a5ce12017-10-13 20:47:09 +0530768 }
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +0530769 } else if (map->flags == FASTRPC_DMAHANDLE_NOMAP) {
770 if (!IS_ERR_OR_NULL(map->handle))
771 ion_free(fl->apps->client, map->handle);
c_mtharue1a5ce12017-10-13 20:47:09 +0530772 } else {
773 int destVM[1] = {VMID_HLOS};
774 int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
775
776 if (map->secure)
777 sess = fl->secsctx;
778 else
779 sess = fl->sctx;
780
781 if (!IS_ERR_OR_NULL(map->handle))
782 ion_free(fl->apps->client, map->handle);
783 if (sess && sess->smmu.enabled) {
784 if (map->size || map->phys)
785 msm_dma_unmap_sg(sess->smmu.dev,
786 map->table->sgl,
787 map->table->nents, DMA_BIDIRECTIONAL,
788 map->buf);
789 }
790 vmid = fl->apps->channel[fl->cid].vmid;
791 if (vmid && map->phys) {
792 int srcVM[2] = {VMID_HLOS, vmid};
793
794 hyp_assign_phys(map->phys, buf_page_size(map->size),
795 srcVM, 2, destVM, destVMperm, 1);
796 }
797
798 if (!IS_ERR_OR_NULL(map->table))
799 dma_buf_unmap_attachment(map->attach, map->table,
800 DMA_BIDIRECTIONAL);
801 if (!IS_ERR_OR_NULL(map->attach))
802 dma_buf_detach(map->buf, map->attach);
803 if (!IS_ERR_OR_NULL(map->buf))
804 dma_buf_put(map->buf);
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700805 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700806 kfree(map);
807}
808
809static int fastrpc_session_alloc(struct fastrpc_channel_ctx *chan, int secure,
810 struct fastrpc_session_ctx **session);
811
812static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530813 unsigned int attr, uintptr_t va, size_t len, int mflags,
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700814 struct fastrpc_mmap **ppmap)
815{
c_mtharue1a5ce12017-10-13 20:47:09 +0530816 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700817 struct fastrpc_session_ctx *sess;
818 struct fastrpc_apps *apps = fl->apps;
c_mtharue1a5ce12017-10-13 20:47:09 +0530819 struct fastrpc_mmap *map = NULL;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530820 struct fastrpc_channel_ctx *chan = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700821 unsigned long attrs;
c_mtharuf931ff92017-11-30 19:35:30 +0530822 dma_addr_t region_phys = 0;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530823 void *region_vaddr = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700824 unsigned long flags;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530825 int err = 0, vmid, cid = -1;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700826
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +0530827 cid = fl->cid;
828 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
829 if (err) {
830 err = -ECHRNG;
831 goto bail;
832 }
833 chan = &apps->channel[cid];
Sathish Ambleyae5ee542017-01-16 22:24:23 -0800834 if (!fastrpc_mmap_find(fl, fd, va, len, mflags, 1, ppmap))
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700835 return 0;
836 map = kzalloc(sizeof(*map), GFP_KERNEL);
837 VERIFY(err, !IS_ERR_OR_NULL(map));
838 if (err)
839 goto bail;
840 INIT_HLIST_NODE(&map->hn);
841 map->flags = mflags;
842 map->refs = 1;
843 map->fl = fl;
844 map->fd = fd;
845 map->attr = attr;
c_mtharue1a5ce12017-10-13 20:47:09 +0530846 if (mflags == ADSP_MMAP_HEAP_ADDR ||
847 mflags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530848 unsigned long dma_attrs = DMA_ATTR_SKIP_ZEROING |
849 DMA_ATTR_NO_KERNEL_MAPPING;
850
c_mtharue1a5ce12017-10-13 20:47:09 +0530851 map->apps = me;
852 map->fl = NULL;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530853 VERIFY(err, !dma_alloc_memory(&region_phys, &region_vaddr,
854 len, dma_attrs));
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700855 if (err)
856 goto bail;
c_mtharuf931ff92017-11-30 19:35:30 +0530857 map->phys = (uintptr_t)region_phys;
c_mtharue1a5ce12017-10-13 20:47:09 +0530858 map->size = len;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +0530859 map->va = (uintptr_t)region_vaddr;
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +0530860 } else if (mflags == FASTRPC_DMAHANDLE_NOMAP) {
861 ion_phys_addr_t iphys;
862
863 VERIFY(err, !IS_ERR_OR_NULL(map->handle =
864 ion_import_dma_buf_fd(fl->apps->client, fd)));
865 if (err)
866 goto bail;
867
868 map->uncached = 1;
869 map->buf = NULL;
870 map->attach = NULL;
871 map->table = NULL;
872 map->va = 0;
873 map->phys = 0;
874
875 err = ion_phys(fl->apps->client, map->handle,
876 &iphys, &map->size);
877 if (err)
878 goto bail;
879 map->phys = (uint64_t)iphys;
c_mtharue1a5ce12017-10-13 20:47:09 +0530880 } else {
c_mtharu7bd6a422017-10-17 18:15:37 +0530881 if (map->attr && (map->attr & FASTRPC_ATTR_KEEP_MAP)) {
882 pr_info("adsprpc: buffer mapped with persist attr %x\n",
883 (unsigned int)map->attr);
884 map->refs = 2;
885 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530886 VERIFY(err, !IS_ERR_OR_NULL(map->handle =
887 ion_import_dma_buf_fd(fl->apps->client, fd)));
888 if (err)
889 goto bail;
890 VERIFY(err, !ion_handle_get_flags(fl->apps->client, map->handle,
891 &flags));
892 if (err)
893 goto bail;
894
c_mtharue1a5ce12017-10-13 20:47:09 +0530895 map->secure = flags & ION_FLAG_SECURE;
896 if (map->secure) {
897 if (!fl->secsctx)
898 err = fastrpc_session_alloc(chan, 1,
899 &fl->secsctx);
900 if (err)
901 goto bail;
902 }
903 if (map->secure)
904 sess = fl->secsctx;
905 else
906 sess = fl->sctx;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +0530907
c_mtharue1a5ce12017-10-13 20:47:09 +0530908 VERIFY(err, !IS_ERR_OR_NULL(sess));
909 if (err)
910 goto bail;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +0530911
912 map->uncached = !ION_IS_CACHED(flags);
913 if (map->attr & FASTRPC_ATTR_NOVA && !sess->smmu.coherent)
914 map->uncached = 1;
915
c_mtharue1a5ce12017-10-13 20:47:09 +0530916 VERIFY(err, !IS_ERR_OR_NULL(map->buf = dma_buf_get(fd)));
917 if (err)
918 goto bail;
919 VERIFY(err, !IS_ERR_OR_NULL(map->attach =
920 dma_buf_attach(map->buf, sess->smmu.dev)));
921 if (err)
922 goto bail;
923 VERIFY(err, !IS_ERR_OR_NULL(map->table =
924 dma_buf_map_attachment(map->attach,
925 DMA_BIDIRECTIONAL)));
926 if (err)
927 goto bail;
928 if (sess->smmu.enabled) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700929 attrs = DMA_ATTR_EXEC_MAPPING;
Tharun Kumar Merugu2e5f12e2017-07-06 12:04:40 +0530930
931 if (map->attr & FASTRPC_ATTR_NON_COHERENT ||
932 (sess->smmu.coherent && map->uncached))
933 attrs |= DMA_ATTR_FORCE_NON_COHERENT;
934 else if (map->attr & FASTRPC_ATTR_COHERENT)
935 attrs |= DMA_ATTR_FORCE_COHERENT;
936
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700937 VERIFY(err, map->table->nents ==
c_mtharue1a5ce12017-10-13 20:47:09 +0530938 msm_dma_map_sg_attrs(sess->smmu.dev,
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700939 map->table->sgl, map->table->nents,
940 DMA_BIDIRECTIONAL, map->buf, attrs));
c_mtharue1a5ce12017-10-13 20:47:09 +0530941 if (err)
942 goto bail;
943 } else {
944 VERIFY(err, map->table->nents == 1);
945 if (err)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700946 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +0530947 }
948 map->phys = sg_dma_address(map->table->sgl);
Tharun Kumar Merugu93f319a2018-02-01 17:35:42 +0530949
c_mtharue1a5ce12017-10-13 20:47:09 +0530950 if (sess->smmu.cb) {
951 map->phys += ((uint64_t)sess->smmu.cb << 32);
952 map->size = sg_dma_len(map->table->sgl);
953 } else {
954 map->size = buf_page_size(len);
955 }
Tharun Kumar Merugu93f319a2018-02-01 17:35:42 +0530956
c_mtharue1a5ce12017-10-13 20:47:09 +0530957 vmid = fl->apps->channel[fl->cid].vmid;
Tharun Kumar Merugu93f319a2018-02-01 17:35:42 +0530958 if (!sess->smmu.enabled && !vmid) {
959 VERIFY(err, map->phys >= me->range.addr &&
960 map->phys + map->size <=
961 me->range.addr + me->range.size);
962 if (err) {
963 pr_err("adsprpc: mmap fail out of range\n");
964 goto bail;
965 }
966 }
c_mtharue1a5ce12017-10-13 20:47:09 +0530967 if (vmid) {
968 int srcVM[1] = {VMID_HLOS};
969 int destVM[2] = {VMID_HLOS, vmid};
970 int destVMperm[2] = {PERM_READ | PERM_WRITE,
971 PERM_READ | PERM_WRITE | PERM_EXEC};
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700972
c_mtharue1a5ce12017-10-13 20:47:09 +0530973 VERIFY(err, !hyp_assign_phys(map->phys,
974 buf_page_size(map->size),
975 srcVM, 1, destVM, destVMperm, 2));
976 if (err)
977 goto bail;
978 }
979 map->va = va;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700980 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700981 map->len = len;
982
983 fastrpc_mmap_add(map);
984 *ppmap = map;
985
986bail:
987 if (err && map)
c_mtharu7bd6a422017-10-17 18:15:37 +0530988 fastrpc_mmap_free(map, 0);
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700989 return err;
990}
991
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +0530992static int fastrpc_buf_alloc(struct fastrpc_file *fl, size_t size,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +0530993 unsigned long dma_attr, uint32_t rflags,
994 int remote, struct fastrpc_buf **obuf)
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700995{
996 int err = 0, vmid;
c_mtharue1a5ce12017-10-13 20:47:09 +0530997 struct fastrpc_buf *buf = NULL, *fr = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -0700998 struct hlist_node *n;
999
1000 VERIFY(err, size > 0);
1001 if (err)
1002 goto bail;
1003
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301004 if (!remote) {
1005 /* find the smallest buffer that fits in the cache */
1006 spin_lock(&fl->hlock);
1007 hlist_for_each_entry_safe(buf, n, &fl->cached_bufs, hn) {
1008 if (buf->size >= size && (!fr || fr->size > buf->size))
1009 fr = buf;
1010 }
1011 if (fr)
1012 hlist_del_init(&fr->hn);
1013 spin_unlock(&fl->hlock);
1014 if (fr) {
1015 *obuf = fr;
1016 return 0;
1017 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001018 }
c_mtharue1a5ce12017-10-13 20:47:09 +05301019 buf = NULL;
1020 VERIFY(err, NULL != (buf = kzalloc(sizeof(*buf), GFP_KERNEL)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001021 if (err)
1022 goto bail;
1023 INIT_HLIST_NODE(&buf->hn);
1024 buf->fl = fl;
c_mtharue1a5ce12017-10-13 20:47:09 +05301025 buf->virt = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001026 buf->phys = 0;
1027 buf->size = size;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301028 buf->dma_attr = dma_attr;
1029 buf->flags = rflags;
1030 buf->raddr = 0;
1031 buf->remote = 0;
1032 buf->virt = dma_alloc_attrs(fl->sctx->smmu.dev, buf->size,
1033 (dma_addr_t *)&buf->phys,
1034 GFP_KERNEL, buf->dma_attr);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001035 if (IS_ERR_OR_NULL(buf->virt)) {
1036 /* free cache and retry */
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301037 fastrpc_cached_buf_list_free(fl);
1038 buf->virt = dma_alloc_attrs(fl->sctx->smmu.dev, buf->size,
1039 (dma_addr_t *)&buf->phys,
1040 GFP_KERNEL, buf->dma_attr);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001041 VERIFY(err, !IS_ERR_OR_NULL(buf->virt));
1042 }
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301043 if (err) {
1044 err = -ENOMEM;
1045 pr_err("adsprpc: %s: %s: dma_alloc_attrs failed for size 0x%zx\n",
1046 current->comm, __func__, size);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001047 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301048 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001049 if (fl->sctx->smmu.cb)
1050 buf->phys += ((uint64_t)fl->sctx->smmu.cb << 32);
1051 vmid = fl->apps->channel[fl->cid].vmid;
1052 if (vmid) {
1053 int srcVM[1] = {VMID_HLOS};
1054 int destVM[2] = {VMID_HLOS, vmid};
1055 int destVMperm[2] = {PERM_READ | PERM_WRITE,
1056 PERM_READ | PERM_WRITE | PERM_EXEC};
1057
1058 VERIFY(err, !hyp_assign_phys(buf->phys, buf_page_size(size),
1059 srcVM, 1, destVM, destVMperm, 2));
1060 if (err)
1061 goto bail;
1062 }
1063
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301064 if (remote) {
1065 INIT_HLIST_NODE(&buf->hn_rem);
1066 spin_lock(&fl->hlock);
1067 hlist_add_head(&buf->hn_rem, &fl->remote_bufs);
1068 spin_unlock(&fl->hlock);
1069 buf->remote = remote;
1070 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001071 *obuf = buf;
1072 bail:
1073 if (err && buf)
1074 fastrpc_buf_free(buf, 0);
1075 return err;
1076}
1077
1078
1079static int context_restore_interrupted(struct fastrpc_file *fl,
Sathish Ambleybae51902017-07-03 15:00:49 -07001080 struct fastrpc_ioctl_invoke_crc *inv,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001081 struct smq_invoke_ctx **po)
1082{
1083 int err = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05301084 struct smq_invoke_ctx *ctx = NULL, *ictx = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001085 struct hlist_node *n;
1086 struct fastrpc_ioctl_invoke *invoke = &inv->inv;
1087
1088 spin_lock(&fl->hlock);
1089 hlist_for_each_entry_safe(ictx, n, &fl->clst.interrupted, hn) {
1090 if (ictx->pid == current->pid) {
1091 if (invoke->sc != ictx->sc || ictx->fl != fl)
1092 err = -1;
1093 else {
1094 ctx = ictx;
1095 hlist_del_init(&ctx->hn);
1096 hlist_add_head(&ctx->hn, &fl->clst.pending);
1097 }
1098 break;
1099 }
1100 }
1101 spin_unlock(&fl->hlock);
1102 if (ctx)
1103 *po = ctx;
1104 return err;
1105}
1106
1107#define CMP(aa, bb) ((aa) == (bb) ? 0 : (aa) < (bb) ? -1 : 1)
1108static int overlap_ptr_cmp(const void *a, const void *b)
1109{
1110 struct overlap *pa = *((struct overlap **)a);
1111 struct overlap *pb = *((struct overlap **)b);
1112 /* sort with lowest starting buffer first */
1113 int st = CMP(pa->start, pb->start);
1114 /* sort with highest ending buffer first */
1115 int ed = CMP(pb->end, pa->end);
1116 return st == 0 ? ed : st;
1117}
1118
Sathish Ambley9466d672017-01-25 10:51:55 -08001119static int context_build_overlap(struct smq_invoke_ctx *ctx)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001120{
Sathish Ambley9466d672017-01-25 10:51:55 -08001121 int i, err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001122 remote_arg_t *lpra = ctx->lpra;
1123 int inbufs = REMOTE_SCALARS_INBUFS(ctx->sc);
1124 int outbufs = REMOTE_SCALARS_OUTBUFS(ctx->sc);
1125 int nbufs = inbufs + outbufs;
1126 struct overlap max;
1127
1128 for (i = 0; i < nbufs; ++i) {
1129 ctx->overs[i].start = (uintptr_t)lpra[i].buf.pv;
1130 ctx->overs[i].end = ctx->overs[i].start + lpra[i].buf.len;
Sathish Ambley9466d672017-01-25 10:51:55 -08001131 if (lpra[i].buf.len) {
1132 VERIFY(err, ctx->overs[i].end > ctx->overs[i].start);
1133 if (err)
1134 goto bail;
1135 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001136 ctx->overs[i].raix = i;
1137 ctx->overps[i] = &ctx->overs[i];
1138 }
c_mtharue1a5ce12017-10-13 20:47:09 +05301139 sort(ctx->overps, nbufs, sizeof(*ctx->overps), overlap_ptr_cmp, NULL);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001140 max.start = 0;
1141 max.end = 0;
1142 for (i = 0; i < nbufs; ++i) {
1143 if (ctx->overps[i]->start < max.end) {
1144 ctx->overps[i]->mstart = max.end;
1145 ctx->overps[i]->mend = ctx->overps[i]->end;
1146 ctx->overps[i]->offset = max.end -
1147 ctx->overps[i]->start;
1148 if (ctx->overps[i]->end > max.end) {
1149 max.end = ctx->overps[i]->end;
1150 } else {
1151 ctx->overps[i]->mend = 0;
1152 ctx->overps[i]->mstart = 0;
1153 }
1154 } else {
1155 ctx->overps[i]->mend = ctx->overps[i]->end;
1156 ctx->overps[i]->mstart = ctx->overps[i]->start;
1157 ctx->overps[i]->offset = 0;
1158 max = *ctx->overps[i];
1159 }
1160 }
Sathish Ambley9466d672017-01-25 10:51:55 -08001161bail:
1162 return err;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001163}
1164
1165#define K_COPY_FROM_USER(err, kernel, dst, src, size) \
1166 do {\
1167 if (!(kernel))\
c_mtharue1a5ce12017-10-13 20:47:09 +05301168 VERIFY(err, 0 == copy_from_user((dst),\
1169 (void const __user *)(src),\
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001170 (size)));\
1171 else\
1172 memmove((dst), (src), (size));\
1173 } while (0)
1174
1175#define K_COPY_TO_USER(err, kernel, dst, src, size) \
1176 do {\
1177 if (!(kernel))\
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301178 VERIFY(err, 0 == copy_to_user((void __user *)(dst),\
c_mtharue1a5ce12017-10-13 20:47:09 +05301179 (src), (size)));\
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001180 else\
1181 memmove((dst), (src), (size));\
1182 } while (0)
1183
1184
1185static void context_free(struct smq_invoke_ctx *ctx);
1186
1187static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
Sathish Ambleybae51902017-07-03 15:00:49 -07001188 struct fastrpc_ioctl_invoke_crc *invokefd,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001189 struct smq_invoke_ctx **po)
1190{
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301191 struct fastrpc_apps *me = &gfa;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301192 int err = 0, bufs, ii, size = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05301193 struct smq_invoke_ctx *ctx = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001194 struct fastrpc_ctx_lst *clst = &fl->clst;
1195 struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
1196
1197 bufs = REMOTE_SCALARS_LENGTH(invoke->sc);
1198 size = bufs * sizeof(*ctx->lpra) + bufs * sizeof(*ctx->maps) +
1199 sizeof(*ctx->fds) * (bufs) +
1200 sizeof(*ctx->attrs) * (bufs) +
1201 sizeof(*ctx->overs) * (bufs) +
1202 sizeof(*ctx->overps) * (bufs);
1203
c_mtharue1a5ce12017-10-13 20:47:09 +05301204 VERIFY(err, NULL != (ctx = kzalloc(sizeof(*ctx) + size, GFP_KERNEL)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001205 if (err)
1206 goto bail;
1207
1208 INIT_HLIST_NODE(&ctx->hn);
1209 hlist_add_fake(&ctx->hn);
1210 ctx->fl = fl;
1211 ctx->maps = (struct fastrpc_mmap **)(&ctx[1]);
1212 ctx->lpra = (remote_arg_t *)(&ctx->maps[bufs]);
1213 ctx->fds = (int *)(&ctx->lpra[bufs]);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301214 if (me->legacy) {
1215 ctx->overs = (struct overlap *)(&ctx->fds[bufs]);
1216 ctx->overps = (struct overlap **)(&ctx->overs[bufs]);
1217 } else {
1218 ctx->attrs = (unsigned int *)(&ctx->fds[bufs]);
1219 ctx->overs = (struct overlap *)(&ctx->attrs[bufs]);
1220 ctx->overps = (struct overlap **)(&ctx->overs[bufs]);
1221 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001222
c_mtharue1a5ce12017-10-13 20:47:09 +05301223 K_COPY_FROM_USER(err, kernel, (void *)ctx->lpra, invoke->pra,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001224 bufs * sizeof(*ctx->lpra));
1225 if (err)
1226 goto bail;
1227
1228 if (invokefd->fds) {
1229 K_COPY_FROM_USER(err, kernel, ctx->fds, invokefd->fds,
1230 bufs * sizeof(*ctx->fds));
1231 if (err)
1232 goto bail;
1233 }
1234 if (invokefd->attrs) {
1235 K_COPY_FROM_USER(err, kernel, ctx->attrs, invokefd->attrs,
1236 bufs * sizeof(*ctx->attrs));
1237 if (err)
1238 goto bail;
1239 }
Sathish Ambleybae51902017-07-03 15:00:49 -07001240 ctx->crc = (uint32_t *)invokefd->crc;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001241 ctx->sc = invoke->sc;
Sathish Ambley9466d672017-01-25 10:51:55 -08001242 if (bufs) {
1243 VERIFY(err, 0 == context_build_overlap(ctx));
1244 if (err)
1245 goto bail;
1246 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001247 ctx->retval = -1;
1248 ctx->pid = current->pid;
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05301249 ctx->tgid = fl->tgid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001250 init_completion(&ctx->work);
c_mtharufdac6892017-10-12 13:09:01 +05301251 ctx->magic = FASTRPC_CTX_MAGIC;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001252
1253 spin_lock(&fl->hlock);
1254 hlist_add_head(&ctx->hn, &clst->pending);
1255 spin_unlock(&fl->hlock);
1256
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301257 spin_lock(&me->ctxlock);
1258 for (ii = 0; ii < FASTRPC_CTX_MAX; ii++) {
1259 if (!me->ctxtable[ii]) {
1260 me->ctxtable[ii] = ctx;
1261 ctx->ctxid = (ptr_to_uint64(ctx) & ~0xFFF)|(ii << 4);
1262 break;
1263 }
1264 }
1265 spin_unlock(&me->ctxlock);
1266 VERIFY(err, ii < FASTRPC_CTX_MAX);
1267 if (err) {
1268 pr_err("adsprpc: out of context memory\n");
1269 goto bail;
1270 }
1271
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001272 *po = ctx;
1273bail:
1274 if (ctx && err)
1275 context_free(ctx);
1276 return err;
1277}
1278
1279static void context_save_interrupted(struct smq_invoke_ctx *ctx)
1280{
1281 struct fastrpc_ctx_lst *clst = &ctx->fl->clst;
1282
1283 spin_lock(&ctx->fl->hlock);
1284 hlist_del_init(&ctx->hn);
1285 hlist_add_head(&ctx->hn, &clst->interrupted);
1286 spin_unlock(&ctx->fl->hlock);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001287}
1288
1289static void context_free(struct smq_invoke_ctx *ctx)
1290{
1291 int i;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301292 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001293 int nbufs = REMOTE_SCALARS_INBUFS(ctx->sc) +
1294 REMOTE_SCALARS_OUTBUFS(ctx->sc);
1295 spin_lock(&ctx->fl->hlock);
1296 hlist_del_init(&ctx->hn);
1297 spin_unlock(&ctx->fl->hlock);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301298 mutex_lock(&ctx->fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001299 for (i = 0; i < nbufs; ++i)
c_mtharu7bd6a422017-10-17 18:15:37 +05301300 fastrpc_mmap_free(ctx->maps[i], 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301301
1302 mutex_unlock(&ctx->fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001303 fastrpc_buf_free(ctx->buf, 1);
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301304 fastrpc_buf_free(ctx->lbuf, 1);
c_mtharufdac6892017-10-12 13:09:01 +05301305 ctx->magic = 0;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301306 ctx->ctxid = 0;
1307
1308 spin_lock(&me->ctxlock);
1309 for (i = 0; i < FASTRPC_CTX_MAX; i++) {
1310 if (me->ctxtable[i] == ctx) {
1311 me->ctxtable[i] = NULL;
1312 break;
1313 }
1314 }
1315 spin_unlock(&me->ctxlock);
1316
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001317 kfree(ctx);
1318}
1319
1320static void context_notify_user(struct smq_invoke_ctx *ctx, int retval)
1321{
1322 ctx->retval = retval;
1323 complete(&ctx->work);
1324}
1325
1326
1327static void fastrpc_notify_users(struct fastrpc_file *me)
1328{
1329 struct smq_invoke_ctx *ictx;
1330 struct hlist_node *n;
1331
1332 spin_lock(&me->hlock);
1333 hlist_for_each_entry_safe(ictx, n, &me->clst.pending, hn) {
1334 complete(&ictx->work);
1335 }
1336 hlist_for_each_entry_safe(ictx, n, &me->clst.interrupted, hn) {
1337 complete(&ictx->work);
1338 }
1339 spin_unlock(&me->hlock);
1340
1341}
1342
Tharun Kumar Merugu77dd5872018-04-02 12:48:17 +05301343
1344static void fastrpc_notify_users_staticpd_pdr(struct fastrpc_file *me)
1345{
1346 struct smq_invoke_ctx *ictx;
1347 struct hlist_node *n;
1348
1349 spin_lock(&me->hlock);
1350 hlist_for_each_entry_safe(ictx, n, &me->clst.pending, hn) {
1351 if (ictx->msg.pid)
1352 complete(&ictx->work);
1353 }
1354 hlist_for_each_entry_safe(ictx, n, &me->clst.interrupted, hn) {
1355 if (ictx->msg.pid)
1356 complete(&ictx->work);
1357 }
1358 spin_unlock(&me->hlock);
1359}
1360
1361
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001362static void fastrpc_notify_drivers(struct fastrpc_apps *me, int cid)
1363{
1364 struct fastrpc_file *fl;
1365 struct hlist_node *n;
1366
1367 spin_lock(&me->hlock);
1368 hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
1369 if (fl->cid == cid)
1370 fastrpc_notify_users(fl);
1371 }
1372 spin_unlock(&me->hlock);
1373
1374}
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05301375
1376static void fastrpc_notify_pdr_drivers(struct fastrpc_apps *me, char *spdname)
1377{
1378 struct fastrpc_file *fl;
1379 struct hlist_node *n;
1380
1381 spin_lock(&me->hlock);
1382 hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
1383 if (fl->spdname && !strcmp(spdname, fl->spdname))
Tharun Kumar Merugu77dd5872018-04-02 12:48:17 +05301384 fastrpc_notify_users_staticpd_pdr(fl);
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05301385 }
1386 spin_unlock(&me->hlock);
1387
1388}
1389
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001390static void context_list_ctor(struct fastrpc_ctx_lst *me)
1391{
1392 INIT_HLIST_HEAD(&me->interrupted);
1393 INIT_HLIST_HEAD(&me->pending);
1394}
1395
1396static void fastrpc_context_list_dtor(struct fastrpc_file *fl)
1397{
1398 struct fastrpc_ctx_lst *clst = &fl->clst;
c_mtharue1a5ce12017-10-13 20:47:09 +05301399 struct smq_invoke_ctx *ictx = NULL, *ctxfree;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001400 struct hlist_node *n;
1401
1402 do {
c_mtharue1a5ce12017-10-13 20:47:09 +05301403 ctxfree = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001404 spin_lock(&fl->hlock);
1405 hlist_for_each_entry_safe(ictx, n, &clst->interrupted, hn) {
1406 hlist_del_init(&ictx->hn);
1407 ctxfree = ictx;
1408 break;
1409 }
1410 spin_unlock(&fl->hlock);
1411 if (ctxfree)
1412 context_free(ctxfree);
1413 } while (ctxfree);
1414 do {
c_mtharue1a5ce12017-10-13 20:47:09 +05301415 ctxfree = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001416 spin_lock(&fl->hlock);
1417 hlist_for_each_entry_safe(ictx, n, &clst->pending, hn) {
1418 hlist_del_init(&ictx->hn);
1419 ctxfree = ictx;
1420 break;
1421 }
1422 spin_unlock(&fl->hlock);
1423 if (ctxfree)
1424 context_free(ctxfree);
1425 } while (ctxfree);
1426}
1427
1428static int fastrpc_file_free(struct fastrpc_file *fl);
1429static void fastrpc_file_list_dtor(struct fastrpc_apps *me)
1430{
1431 struct fastrpc_file *fl, *free;
1432 struct hlist_node *n;
1433
1434 do {
c_mtharue1a5ce12017-10-13 20:47:09 +05301435 free = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001436 spin_lock(&me->hlock);
1437 hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
1438 hlist_del_init(&fl->hn);
1439 free = fl;
1440 break;
1441 }
1442 spin_unlock(&me->hlock);
1443 if (free)
1444 fastrpc_file_free(free);
1445 } while (free);
1446}
1447
1448static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
1449{
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301450 struct fastrpc_apps *me = &gfa;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301451 remote_arg64_t *rpra, *lrpra;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001452 remote_arg_t *lpra = ctx->lpra;
1453 struct smq_invoke_buf *list;
1454 struct smq_phy_page *pages, *ipage;
1455 uint32_t sc = ctx->sc;
1456 int inbufs = REMOTE_SCALARS_INBUFS(sc);
1457 int outbufs = REMOTE_SCALARS_OUTBUFS(sc);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001458 int handles, bufs = inbufs + outbufs;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001459 uintptr_t args;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301460 size_t rlen = 0, copylen = 0, metalen = 0, lrpralen = 0;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001461 int i, oix;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001462 int err = 0;
1463 int mflags = 0;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001464 uint64_t *fdlist;
Sathish Ambleybae51902017-07-03 15:00:49 -07001465 uint32_t *crclist;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301466 int64_t *perf_counter = getperfcounter(ctx->fl, PERF_COUNT);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001467
1468 /* calculate size of the metadata */
c_mtharue1a5ce12017-10-13 20:47:09 +05301469 rpra = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001470 list = smq_invoke_buf_start(rpra, sc);
1471 pages = smq_phy_page_start(sc, list);
1472 ipage = pages;
1473
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301474 PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_MAP),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001475 for (i = 0; i < bufs; ++i) {
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301476 uintptr_t buf = (uintptr_t)lpra[i].buf.pv;
1477 size_t len = lpra[i].buf.len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001478
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301479 mutex_lock(&ctx->fl->fl_map_mutex);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301480 if (ctx->fds[i] && (ctx->fds[i] != -1)) {
1481 unsigned int attrs = 0;
1482
1483 if (ctx->attrs)
1484 attrs = ctx->attrs[i];
1485
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001486 fastrpc_mmap_create(ctx->fl, ctx->fds[i],
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301487 attrs, buf, len,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001488 mflags, &ctx->maps[i]);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301489 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301490 mutex_unlock(&ctx->fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001491 ipage += 1;
1492 }
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301493 PERF_END);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001494 handles = REMOTE_SCALARS_INHANDLES(sc) + REMOTE_SCALARS_OUTHANDLES(sc);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301495 mutex_lock(&ctx->fl->fl_map_mutex);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001496 for (i = bufs; i < bufs + handles; i++) {
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +05301497 int dmaflags = 0;
1498
1499 if (ctx->attrs && (ctx->attrs[i] & FASTRPC_ATTR_NOMAP))
1500 dmaflags = FASTRPC_DMAHANDLE_NOMAP;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001501 VERIFY(err, !fastrpc_mmap_create(ctx->fl, ctx->fds[i],
Tharun Kumar Merugu35a94a52018-02-01 21:09:04 +05301502 FASTRPC_ATTR_NOVA, 0, 0, dmaflags, &ctx->maps[i]));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301503 if (err) {
1504 mutex_unlock(&ctx->fl->fl_map_mutex);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001505 goto bail;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301506 }
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001507 ipage += 1;
1508 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301509 mutex_unlock(&ctx->fl->fl_map_mutex);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301510 if (!me->legacy) {
1511 metalen = copylen = (size_t)&ipage[0] +
1512 (sizeof(uint64_t) * M_FDLIST) +
1513 (sizeof(uint32_t) * M_CRCLIST);
1514 } else {
1515 metalen = copylen = (size_t)&ipage[0];
1516 }
Sathish Ambleybae51902017-07-03 15:00:49 -07001517
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301518 /* allocate new local rpra buffer */
1519 lrpralen = (size_t)&list[0];
1520 if (lrpralen) {
1521 err = fastrpc_buf_alloc(ctx->fl, lrpralen, 0, 0, 0, &ctx->lbuf);
1522 if (err)
1523 goto bail;
1524 }
1525 if (ctx->lbuf->virt)
1526 memset(ctx->lbuf->virt, 0, lrpralen);
1527
1528 lrpra = ctx->lbuf->virt;
1529 ctx->lrpra = lrpra;
1530
1531 /* calculate len required for copying */
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001532 for (oix = 0; oix < inbufs + outbufs; ++oix) {
1533 int i = ctx->overps[oix]->raix;
Sathish Ambleyd209c1e2016-12-13 15:27:30 -08001534 uintptr_t mstart, mend;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301535 size_t len = lpra[i].buf.len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001536
1537 if (!len)
1538 continue;
1539 if (ctx->maps[i])
1540 continue;
1541 if (ctx->overps[oix]->offset == 0)
1542 copylen = ALIGN(copylen, BALIGN);
Sathish Ambleyd209c1e2016-12-13 15:27:30 -08001543 mstart = ctx->overps[oix]->mstart;
1544 mend = ctx->overps[oix]->mend;
1545 VERIFY(err, (mend - mstart) <= LONG_MAX);
1546 if (err)
1547 goto bail;
1548 copylen += mend - mstart;
1549 VERIFY(err, copylen >= 0);
1550 if (err)
1551 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001552 }
1553 ctx->used = copylen;
1554
1555 /* allocate new buffer */
1556 if (copylen) {
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05301557 err = fastrpc_buf_alloc(ctx->fl, copylen, 0, 0, 0, &ctx->buf);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001558 if (err)
1559 goto bail;
1560 }
Tharun Kumar Merugue3361f92017-06-22 10:45:43 +05301561 if (ctx->buf->virt && metalen <= copylen)
1562 memset(ctx->buf->virt, 0, metalen);
1563
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001564 /* copy metadata */
1565 rpra = ctx->buf->virt;
1566 ctx->rpra = rpra;
1567 list = smq_invoke_buf_start(rpra, sc);
1568 pages = smq_phy_page_start(sc, list);
1569 ipage = pages;
1570 args = (uintptr_t)ctx->buf->virt + metalen;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001571 for (i = 0; i < bufs + handles; ++i) {
1572 if (lpra[i].buf.len)
1573 list[i].num = 1;
1574 else
1575 list[i].num = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001576 list[i].pgidx = ipage - pages;
1577 ipage++;
1578 }
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +05301579
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001580 /* map ion buffers */
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301581 PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_MAP),
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301582 for (i = 0; rpra && lrpra && i < inbufs + outbufs; ++i) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001583 struct fastrpc_mmap *map = ctx->maps[i];
1584 uint64_t buf = ptr_to_uint64(lpra[i].buf.pv);
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301585 size_t len = lpra[i].buf.len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001586
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301587 rpra[i].buf.pv = lrpra[i].buf.pv = 0;
1588 rpra[i].buf.len = lrpra[i].buf.len = len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001589 if (!len)
1590 continue;
1591 if (map) {
1592 struct vm_area_struct *vma;
1593 uintptr_t offset;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301594 uint64_t num = buf_num_pages(buf, len);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001595 int idx = list[i].pgidx;
1596
1597 if (map->attr & FASTRPC_ATTR_NOVA) {
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001598 offset = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001599 } else {
1600 down_read(&current->mm->mmap_sem);
1601 VERIFY(err, NULL != (vma = find_vma(current->mm,
1602 map->va)));
1603 if (err) {
1604 up_read(&current->mm->mmap_sem);
1605 goto bail;
1606 }
1607 offset = buf_page_start(buf) - vma->vm_start;
1608 up_read(&current->mm->mmap_sem);
1609 VERIFY(err, offset < (uintptr_t)map->size);
1610 if (err)
1611 goto bail;
1612 }
1613 pages[idx].addr = map->phys + offset;
1614 pages[idx].size = num << PAGE_SHIFT;
1615 }
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301616 rpra[i].buf.pv = lrpra[i].buf.pv = buf;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001617 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001618 PERF_END);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001619 for (i = bufs; i < bufs + handles; ++i) {
1620 struct fastrpc_mmap *map = ctx->maps[i];
1621
1622 pages[i].addr = map->phys;
1623 pages[i].size = map->size;
1624 }
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301625 if (!me->legacy) {
1626 fdlist = (uint64_t *)&pages[bufs + handles];
1627 for (i = 0; i < M_FDLIST; i++)
1628 fdlist[i] = 0;
1629 crclist = (uint32_t *)&fdlist[M_FDLIST];
1630 memset(crclist, 0, sizeof(uint32_t)*M_CRCLIST);
1631 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001632
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001633 /* copy non ion buffers */
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301634 PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_COPY),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001635 rlen = copylen - metalen;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301636 for (oix = 0; rpra && lrpra && oix < inbufs + outbufs; ++oix) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001637 int i = ctx->overps[oix]->raix;
1638 struct fastrpc_mmap *map = ctx->maps[i];
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301639 size_t mlen;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001640 uint64_t buf;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05301641 size_t len = lpra[i].buf.len;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001642
1643 if (!len)
1644 continue;
1645 if (map)
1646 continue;
1647 if (ctx->overps[oix]->offset == 0) {
1648 rlen -= ALIGN(args, BALIGN) - args;
1649 args = ALIGN(args, BALIGN);
1650 }
Sathish Ambleyd209c1e2016-12-13 15:27:30 -08001651 mlen = ctx->overps[oix]->mend - ctx->overps[oix]->mstart;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001652 VERIFY(err, rlen >= mlen);
1653 if (err)
1654 goto bail;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301655 rpra[i].buf.pv = lrpra[i].buf.pv =
1656 (args - ctx->overps[oix]->offset);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001657 pages[list[i].pgidx].addr = ctx->buf->phys -
1658 ctx->overps[oix]->offset +
1659 (copylen - rlen);
1660 pages[list[i].pgidx].addr =
1661 buf_page_start(pages[list[i].pgidx].addr);
1662 buf = rpra[i].buf.pv;
1663 pages[list[i].pgidx].size = buf_num_pages(buf, len) * PAGE_SIZE;
1664 if (i < inbufs) {
1665 K_COPY_FROM_USER(err, kernel, uint64_to_ptr(buf),
1666 lpra[i].buf.pv, len);
1667 if (err)
1668 goto bail;
1669 }
1670 args = args + mlen;
1671 rlen -= mlen;
1672 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001673 PERF_END);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001674
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05301675 PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_FLUSH),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001676 for (oix = 0; oix < inbufs + outbufs; ++oix) {
1677 int i = ctx->overps[oix]->raix;
1678 struct fastrpc_mmap *map = ctx->maps[i];
1679
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001680 if (map && map->uncached)
1681 continue;
Tharun Kumar Merugu2e5f12e2017-07-06 12:04:40 +05301682 if (ctx->fl->sctx->smmu.coherent &&
1683 !(map && (map->attr & FASTRPC_ATTR_NON_COHERENT)))
1684 continue;
1685 if (map && (map->attr & FASTRPC_ATTR_COHERENT))
1686 continue;
1687
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301688 if (rpra && lrpra && rpra[i].buf.len &&
1689 ctx->overps[oix]->mstart) {
Tharun Kumar Merugub67336e2017-08-08 18:56:03 +05301690 if (map && map->handle)
1691 msm_ion_do_cache_op(ctx->fl->apps->client,
1692 map->handle,
1693 uint64_to_ptr(rpra[i].buf.pv),
1694 rpra[i].buf.len,
1695 ION_IOC_CLEAN_INV_CACHES);
1696 else
1697 dmac_flush_range(uint64_to_ptr(rpra[i].buf.pv),
1698 uint64_to_ptr(rpra[i].buf.pv
1699 + rpra[i].buf.len));
1700 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001701 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001702 PERF_END);
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301703 for (i = bufs; rpra && lrpra && i < bufs + handles; i++) {
1704 rpra[i].dma.fd = lrpra[i].dma.fd = ctx->fds[i];
1705 rpra[i].dma.len = lrpra[i].dma.len = (uint32_t)lpra[i].buf.len;
1706 rpra[i].dma.offset = lrpra[i].dma.offset =
1707 (uint32_t)(uintptr_t)lpra[i].buf.pv;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001708 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08001709
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001710 bail:
1711 return err;
1712}
1713
1714static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
1715 remote_arg_t *upra)
1716{
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301717 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001718 uint32_t sc = ctx->sc;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001719 struct smq_invoke_buf *list;
1720 struct smq_phy_page *pages;
1721 struct fastrpc_mmap *mmap;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301722 uint64_t *fdlist = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07001723 uint32_t *crclist = NULL;
1724
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301725 remote_arg64_t *rpra = ctx->lrpra;
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001726 int i, inbufs, outbufs, handles;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001727 int err = 0;
1728
1729 inbufs = REMOTE_SCALARS_INBUFS(sc);
1730 outbufs = REMOTE_SCALARS_OUTBUFS(sc);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001731 handles = REMOTE_SCALARS_INHANDLES(sc) + REMOTE_SCALARS_OUTHANDLES(sc);
1732 list = smq_invoke_buf_start(ctx->rpra, sc);
1733 pages = smq_phy_page_start(sc, list);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301734 if (!me->legacy) {
1735 fdlist = (uint64_t *)(pages + inbufs + outbufs + handles);
1736 crclist = (uint32_t *)(fdlist + M_FDLIST);
1737 }
Sathish Ambleybae51902017-07-03 15:00:49 -07001738
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001739 for (i = inbufs; i < inbufs + outbufs; ++i) {
1740 if (!ctx->maps[i]) {
1741 K_COPY_TO_USER(err, kernel,
1742 ctx->lpra[i].buf.pv,
1743 uint64_to_ptr(rpra[i].buf.pv),
1744 rpra[i].buf.len);
1745 if (err)
1746 goto bail;
1747 } else {
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301748 mutex_lock(&ctx->fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05301749 fastrpc_mmap_free(ctx->maps[i], 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301750 mutex_unlock(&ctx->fl->fl_map_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05301751 ctx->maps[i] = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001752 }
1753 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301754 mutex_lock(&ctx->fl->fl_map_mutex);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301755 if (fdlist && (inbufs + outbufs + handles)) {
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001756 for (i = 0; i < M_FDLIST; i++) {
1757 if (!fdlist[i])
1758 break;
1759 if (!fastrpc_mmap_find(ctx->fl, (int)fdlist[i], 0, 0,
Sathish Ambleyae5ee542017-01-16 22:24:23 -08001760 0, 0, &mmap))
c_mtharu7bd6a422017-10-17 18:15:37 +05301761 fastrpc_mmap_free(mmap, 0);
Sathish Ambley58dc64d2016-11-29 17:11:53 -08001762 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001763 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05301764 mutex_unlock(&ctx->fl->fl_map_mutex);
Sathish Ambleybae51902017-07-03 15:00:49 -07001765 if (ctx->crc && crclist && rpra)
c_mtharue1a5ce12017-10-13 20:47:09 +05301766 K_COPY_TO_USER(err, kernel, ctx->crc,
Sathish Ambleybae51902017-07-03 15:00:49 -07001767 crclist, M_CRCLIST*sizeof(uint32_t));
1768
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001769 bail:
1770 return err;
1771}
1772
1773static void inv_args_pre(struct smq_invoke_ctx *ctx)
1774{
1775 int i, inbufs, outbufs;
1776 uint32_t sc = ctx->sc;
1777 remote_arg64_t *rpra = ctx->rpra;
1778 uintptr_t end;
1779
1780 inbufs = REMOTE_SCALARS_INBUFS(sc);
1781 outbufs = REMOTE_SCALARS_OUTBUFS(sc);
1782 for (i = inbufs; i < inbufs + outbufs; ++i) {
1783 struct fastrpc_mmap *map = ctx->maps[i];
1784
1785 if (map && map->uncached)
1786 continue;
1787 if (!rpra[i].buf.len)
1788 continue;
Tharun Kumar Merugu2e5f12e2017-07-06 12:04:40 +05301789 if (ctx->fl->sctx->smmu.coherent &&
1790 !(map && (map->attr & FASTRPC_ATTR_NON_COHERENT)))
1791 continue;
1792 if (map && (map->attr & FASTRPC_ATTR_COHERENT))
1793 continue;
1794
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001795 if (buf_page_start(ptr_to_uint64((void *)rpra)) ==
1796 buf_page_start(rpra[i].buf.pv))
1797 continue;
Tharun Kumar Merugub67336e2017-08-08 18:56:03 +05301798 if (!IS_CACHE_ALIGNED((uintptr_t)
1799 uint64_to_ptr(rpra[i].buf.pv))) {
1800 if (map && map->handle)
1801 msm_ion_do_cache_op(ctx->fl->apps->client,
1802 map->handle,
1803 uint64_to_ptr(rpra[i].buf.pv),
1804 sizeof(uintptr_t),
1805 ION_IOC_CLEAN_INV_CACHES);
1806 else
1807 dmac_flush_range(
1808 uint64_to_ptr(rpra[i].buf.pv), (char *)
1809 uint64_to_ptr(rpra[i].buf.pv + 1));
1810 }
1811
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001812 end = (uintptr_t)uint64_to_ptr(rpra[i].buf.pv +
1813 rpra[i].buf.len);
Tharun Kumar Merugub67336e2017-08-08 18:56:03 +05301814 if (!IS_CACHE_ALIGNED(end)) {
1815 if (map && map->handle)
1816 msm_ion_do_cache_op(ctx->fl->apps->client,
1817 map->handle,
1818 uint64_to_ptr(end),
1819 sizeof(uintptr_t),
1820 ION_IOC_CLEAN_INV_CACHES);
1821 else
1822 dmac_flush_range((char *)end,
1823 (char *)end + 1);
1824 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001825 }
1826}
1827
1828static void inv_args(struct smq_invoke_ctx *ctx)
1829{
1830 int i, inbufs, outbufs;
1831 uint32_t sc = ctx->sc;
Tharun Kumar Merugub31cc732019-05-07 00:39:43 +05301832 remote_arg64_t *rpra = ctx->lrpra;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001833
1834 inbufs = REMOTE_SCALARS_INBUFS(sc);
1835 outbufs = REMOTE_SCALARS_OUTBUFS(sc);
1836 for (i = inbufs; i < inbufs + outbufs; ++i) {
1837 struct fastrpc_mmap *map = ctx->maps[i];
1838
1839 if (map && map->uncached)
1840 continue;
1841 if (!rpra[i].buf.len)
1842 continue;
Tharun Kumar Merugu2e5f12e2017-07-06 12:04:40 +05301843 if (ctx->fl->sctx->smmu.coherent &&
1844 !(map && (map->attr & FASTRPC_ATTR_NON_COHERENT)))
1845 continue;
1846 if (map && (map->attr & FASTRPC_ATTR_COHERENT))
1847 continue;
1848
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001849 if (buf_page_start(ptr_to_uint64((void *)rpra)) ==
1850 buf_page_start(rpra[i].buf.pv)) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001851 continue;
1852 }
1853 if (map && map->handle)
1854 msm_ion_do_cache_op(ctx->fl->apps->client, map->handle,
1855 (char *)uint64_to_ptr(rpra[i].buf.pv),
1856 rpra[i].buf.len, ION_IOC_INV_CACHES);
1857 else
1858 dmac_inv_range((char *)uint64_to_ptr(rpra[i].buf.pv),
1859 (char *)uint64_to_ptr(rpra[i].buf.pv
1860 + rpra[i].buf.len));
1861 }
1862
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001863}
1864
1865static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx,
1866 uint32_t kernel, uint32_t handle)
1867{
1868 struct smq_msg *msg = &ctx->msg;
1869 struct fastrpc_file *fl = ctx->fl;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05301870 int err = 0, len, cid = -1;
1871 struct fastrpc_channel_ctx *channel_ctx = NULL;
1872
1873 cid = fl->cid;
1874 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
1875 if (err) {
1876 err = -ECHRNG;
1877 goto bail;
1878 }
1879 channel_ctx = &fl->apps->channel[fl->cid];
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001880
c_mtharue1a5ce12017-10-13 20:47:09 +05301881 VERIFY(err, NULL != channel_ctx->chan);
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05301882 if (err) {
1883 err = -ECHRNG;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001884 goto bail;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05301885 }
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05301886 msg->pid = fl->tgid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001887 msg->tid = current->pid;
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05301888 if (fl->sessionid)
1889 msg->tid |= (1 << SESSION_ID_INDEX);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001890 if (kernel)
1891 msg->pid = 0;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301892 msg->invoke.header.ctx = ctx->ctxid | fl->pd;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001893 msg->invoke.header.handle = handle;
1894 msg->invoke.header.sc = ctx->sc;
1895 msg->invoke.page.addr = ctx->buf ? ctx->buf->phys : 0;
1896 msg->invoke.page.size = buf_page_size(ctx->used);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301897 if (fl->apps->glink) {
1898 if (fl->ssrcount != channel_ctx->ssrcount) {
1899 err = -ECONNRESET;
1900 goto bail;
1901 }
1902 VERIFY(err, channel_ctx->link.port_state ==
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001903 FASTRPC_LINK_CONNECTED);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301904 if (err)
1905 goto bail;
1906 err = glink_tx(channel_ctx->chan,
1907 (void *)&fl->apps->channel[fl->cid], msg, sizeof(*msg),
1908 GLINK_TX_REQ_INTENT);
1909 } else {
1910 spin_lock(&fl->apps->hlock);
1911 len = smd_write((smd_channel_t *)
1912 channel_ctx->chan,
1913 msg, sizeof(*msg));
1914 spin_unlock(&fl->apps->hlock);
1915 VERIFY(err, len == sizeof(*msg));
1916 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001917 bail:
1918 return err;
1919}
1920
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301921static void fastrpc_smd_read_handler(int cid)
1922{
1923 struct fastrpc_apps *me = &gfa;
1924 struct smq_invoke_rsp rsp = {0};
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301925 int ret = 0, err = 0;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301926 uint32_t index;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301927
1928 do {
1929 ret = smd_read_from_cb(me->channel[cid].chan, &rsp,
1930 sizeof(rsp));
1931 if (ret != sizeof(rsp))
1932 break;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301933
1934 index = (uint32_t)((rsp.ctx & FASTRPC_CTXID_MASK) >> 4);
1935 VERIFY(err, index < FASTRPC_CTX_MAX);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301936 if (err)
1937 goto bail;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301938
1939 VERIFY(err, !IS_ERR_OR_NULL(me->ctxtable[index]));
1940 if (err)
1941 goto bail;
1942
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05301943 VERIFY(err, ((me->ctxtable[index]->ctxid == (rsp.ctx & ~3)) &&
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301944 me->ctxtable[index]->magic == FASTRPC_CTX_MAGIC));
1945 if (err)
1946 goto bail;
1947
1948 context_notify_user(me->ctxtable[index], rsp.retval);
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05301949 } while (ret == sizeof(rsp));
1950bail:
1951 if (err)
1952 pr_err("adsprpc: invalid response or context\n");
1953
1954}
1955
1956static void smd_event_handler(void *priv, unsigned int event)
1957{
1958 struct fastrpc_apps *me = &gfa;
1959 int cid = (int)(uintptr_t)priv;
1960
1961 switch (event) {
1962 case SMD_EVENT_OPEN:
1963 complete(&me->channel[cid].workport);
1964 break;
1965 case SMD_EVENT_CLOSE:
1966 fastrpc_notify_drivers(me, cid);
1967 break;
1968 case SMD_EVENT_DATA:
1969 fastrpc_smd_read_handler(cid);
1970 break;
1971 }
1972}
1973
1974
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001975static void fastrpc_init(struct fastrpc_apps *me)
1976{
1977 int i;
1978
1979 INIT_HLIST_HEAD(&me->drivers);
Tharun Kumar Merugubcd6fbf2018-01-04 17:49:34 +05301980 INIT_HLIST_HEAD(&me->maps);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001981 spin_lock_init(&me->hlock);
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05301982 spin_lock_init(&me->ctxlock);
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05301983 mutex_init(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001984 me->channel = &gcinfo[0];
1985 for (i = 0; i < NUM_CHANNELS; i++) {
1986 init_completion(&me->channel[i].work);
Tharun Kumar Merugu53a8ec92017-07-14 15:52:49 +05301987 init_completion(&me->channel[i].workport);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001988 me->channel[i].sesscount = 0;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05301989 /* All channels are secure by default except CDSP */
1990 me->channel[i].secure = SECURE_CHANNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001991 }
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05301992 /* Set CDSP channel to non secure */
1993 me->channel[CDSP_DOMAIN_ID].secure = NON_SECURE_CHANNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07001994}
1995
1996static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl);
1997
1998static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
1999 uint32_t kernel,
Sathish Ambleybae51902017-07-03 15:00:49 -07002000 struct fastrpc_ioctl_invoke_crc *inv)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002001{
c_mtharue1a5ce12017-10-13 20:47:09 +05302002 struct smq_invoke_ctx *ctx = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002003 struct fastrpc_ioctl_invoke *invoke = &inv->inv;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05302004 int err = 0, cid = -1, interrupted = 0;
Maria Yu757199c2017-09-22 16:05:49 +08002005 struct timespec invoket = {0};
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05302006 int64_t *perf_counter = NULL;
2007
2008 cid = fl->cid;
2009 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
2010 if (err) {
2011 err = -ECHRNG;
2012 goto bail;
2013 }
2014 VERIFY(err, fl->sctx != NULL);
2015 if (err) {
2016 err = -EBADR;
2017 goto bail;
2018 }
2019 perf_counter = getperfcounter(fl, PERF_COUNT);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002020
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002021 if (fl->profile)
2022 getnstimeofday(&invoket);
Tharun Kumar Merugue3edf3e2017-07-27 12:34:07 +05302023
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302024 if (!kernel) {
2025 VERIFY(err, invoke->handle != FASTRPC_STATIC_HANDLE_KERNEL);
2026 if (err) {
2027 pr_err("adsprpc: ERROR: %s: user application %s trying to send a kernel RPC message to channel %d",
2028 __func__, current->comm, cid);
2029 goto bail;
2030 }
2031 }
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302032
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002033 if (!kernel) {
2034 VERIFY(err, 0 == context_restore_interrupted(fl, inv,
2035 &ctx));
2036 if (err)
2037 goto bail;
2038 if (fl->sctx->smmu.faults)
2039 err = FASTRPC_ENOSUCH;
2040 if (err)
2041 goto bail;
2042 if (ctx)
2043 goto wait;
2044 }
2045
2046 VERIFY(err, 0 == context_alloc(fl, kernel, inv, &ctx));
2047 if (err)
2048 goto bail;
2049
2050 if (REMOTE_SCALARS_LENGTH(ctx->sc)) {
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302051 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_GETARGS),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002052 VERIFY(err, 0 == get_args(kernel, ctx));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002053 PERF_END);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002054 if (err)
2055 goto bail;
2056 }
2057
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302058 if (!fl->sctx->smmu.coherent) {
2059 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_INVARGS),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002060 inv_args_pre(ctx);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302061 PERF_END);
2062 }
2063
2064 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_LINK),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002065 VERIFY(err, 0 == fastrpc_invoke_send(ctx, kernel, invoke->handle));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002066 PERF_END);
2067
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002068 if (err)
2069 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002070 wait:
2071 if (kernel)
2072 wait_for_completion(&ctx->work);
2073 else {
2074 interrupted = wait_for_completion_interruptible(&ctx->work);
2075 VERIFY(err, 0 == (err = interrupted));
2076 if (err)
2077 goto bail;
2078 }
Mohammed Nayeem Ur Rahman32ba95d2019-07-26 17:31:37 +05302079 if (ctx->handle)
2080 glink_rx_done(ctx->handle, ctx->ptr, true);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302081 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_INVARGS),
Sathish Ambleyc432b502017-06-05 12:03:42 -07002082 if (!fl->sctx->smmu.coherent)
2083 inv_args(ctx);
2084 PERF_END);
2085
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002086 VERIFY(err, 0 == (err = ctx->retval));
2087 if (err)
2088 goto bail;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002089
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302090 PERF(fl->profile, GET_COUNTER(perf_counter, PERF_PUTARGS),
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002091 VERIFY(err, 0 == put_args(kernel, ctx, invoke->pra));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002092 PERF_END);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002093 if (err)
2094 goto bail;
2095 bail:
2096 if (ctx && interrupted == -ERESTARTSYS)
2097 context_save_interrupted(ctx);
2098 else if (ctx)
2099 context_free(ctx);
2100 if (fl->ssrcount != fl->apps->channel[cid].ssrcount)
2101 err = ECONNRESET;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002102
2103 if (fl->profile && !interrupted) {
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302104 if (invoke->handle != FASTRPC_STATIC_HANDLE_LISTENER) {
2105 int64_t *count = GET_COUNTER(perf_counter, PERF_INVOKE);
2106
2107 if (count)
2108 *count += getnstimediff(&invoket);
2109 }
2110 if (invoke->handle > FASTRPC_STATIC_HANDLE_MAX) {
2111 int64_t *count = GET_COUNTER(perf_counter, PERF_COUNT);
2112
2113 if (count)
2114 *count = *count+1;
2115 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08002116 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002117 return err;
2118}
2119
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302120static int fastrpc_get_adsp_session(char *name, int *session)
2121{
2122 struct fastrpc_apps *me = &gfa;
2123 int err = 0, i;
2124
2125 for (i = 0; i < NUM_SESSIONS; i++) {
2126 if (!me->channel[0].spd[i].spdname)
2127 continue;
2128 if (!strcmp(name, me->channel[0].spd[i].spdname))
2129 break;
2130 }
2131 VERIFY(err, i < NUM_SESSIONS);
2132 if (err)
2133 goto bail;
2134 *session = i;
2135bail:
2136 return err;
2137}
2138
2139static int fastrpc_mmap_remove_pdr(struct fastrpc_file *fl);
Sathish Ambley36849af2017-02-02 09:35:55 -08002140static int fastrpc_channel_open(struct fastrpc_file *fl);
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302141static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002142static int fastrpc_init_process(struct fastrpc_file *fl,
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002143 struct fastrpc_ioctl_init_attrs *uproc)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002144{
2145 int err = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302146 struct fastrpc_apps *me = &gfa;
Sathish Ambleybae51902017-07-03 15:00:49 -07002147 struct fastrpc_ioctl_invoke_crc ioctl;
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002148 struct fastrpc_ioctl_init *init = &uproc->init;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002149 struct smq_phy_page pages[1];
c_mtharue1a5ce12017-10-13 20:47:09 +05302150 struct fastrpc_mmap *file = NULL, *mem = NULL;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302151 struct fastrpc_buf *imem = NULL;
2152 unsigned long imem_dma_attr = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302153 char *proc_name = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002154
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302155 VERIFY(err, 0 == (err = fastrpc_channel_open(fl)));
Sathish Ambley36849af2017-02-02 09:35:55 -08002156 if (err)
2157 goto bail;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302158 if (init->flags == FASTRPC_INIT_ATTACH ||
2159 init->flags == FASTRPC_INIT_ATTACH_SENSORS) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002160 remote_arg_t ra[1];
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302161 int tgid = fl->tgid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002162
2163 ra[0].buf.pv = (void *)&tgid;
2164 ra[0].buf.len = sizeof(tgid);
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302165 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002166 ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 0);
2167 ioctl.inv.pra = ra;
c_mtharue1a5ce12017-10-13 20:47:09 +05302168 ioctl.fds = NULL;
2169 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002170 ioctl.crc = NULL;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302171 if (init->flags == FASTRPC_INIT_ATTACH)
2172 fl->pd = 0;
2173 else if (init->flags == FASTRPC_INIT_ATTACH_SENSORS) {
2174 fl->spdname = SENSORS_PDR_SERVICE_LOCATION_CLIENT_NAME;
2175 fl->pd = 2;
2176 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002177 VERIFY(err, !(err = fastrpc_internal_invoke(fl,
2178 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2179 if (err)
2180 goto bail;
2181 } else if (init->flags == FASTRPC_INIT_CREATE) {
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002182 remote_arg_t ra[6];
2183 int fds[6];
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002184 int mflags = 0;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302185 int memlen;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002186 struct {
2187 int pgid;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302188 unsigned int namelen;
2189 unsigned int filelen;
2190 unsigned int pageslen;
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002191 int attrs;
2192 int siglen;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002193 } inbuf;
2194
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302195 inbuf.pgid = fl->tgid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002196 inbuf.namelen = strlen(current->comm) + 1;
2197 inbuf.filelen = init->filelen;
2198 fl->pd = 1;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302199
Tharun Kumar Merugudf852892017-12-07 16:27:37 +05302200 VERIFY(err, access_ok(0, (void __user *)init->file,
2201 init->filelen));
2202 if (err)
2203 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002204 if (init->filelen) {
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302205 mutex_lock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002206 VERIFY(err, !fastrpc_mmap_create(fl, init->filefd, 0,
2207 init->file, init->filelen, mflags, &file));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302208 mutex_unlock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002209 if (err)
2210 goto bail;
2211 }
2212 inbuf.pageslen = 1;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302213
2214 VERIFY(err, !init->mem);
2215 if (err) {
2216 err = -EINVAL;
2217 pr_err("adsprpc: %s: %s: ERROR: donated memory allocated in userspace\n",
2218 current->comm, __func__);
2219 goto bail;
2220 }
2221 memlen = ALIGN(max(1024*1024*3, (int)init->filelen * 4),
2222 1024*1024);
2223 imem_dma_attr = DMA_ATTR_EXEC_MAPPING |
2224 DMA_ATTR_NO_KERNEL_MAPPING |
2225 DMA_ATTR_FORCE_NON_COHERENT;
2226 err = fastrpc_buf_alloc(fl, memlen, imem_dma_attr, 0, 0, &imem);
Tharun Kumar Merugudf852892017-12-07 16:27:37 +05302227 if (err)
2228 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302229 fl->init_mem = imem;
2230
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002231 inbuf.pageslen = 1;
2232 ra[0].buf.pv = (void *)&inbuf;
2233 ra[0].buf.len = sizeof(inbuf);
2234 fds[0] = 0;
2235
2236 ra[1].buf.pv = (void *)current->comm;
2237 ra[1].buf.len = inbuf.namelen;
2238 fds[1] = 0;
2239
2240 ra[2].buf.pv = (void *)init->file;
2241 ra[2].buf.len = inbuf.filelen;
2242 fds[2] = init->filefd;
2243
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302244 pages[0].addr = imem->phys;
2245 pages[0].size = imem->size;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002246 ra[3].buf.pv = (void *)pages;
2247 ra[3].buf.len = 1 * sizeof(*pages);
2248 fds[3] = 0;
2249
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002250 inbuf.attrs = uproc->attrs;
2251 ra[4].buf.pv = (void *)&(inbuf.attrs);
2252 ra[4].buf.len = sizeof(inbuf.attrs);
2253 fds[4] = 0;
2254
2255 inbuf.siglen = uproc->siglen;
2256 ra[5].buf.pv = (void *)&(inbuf.siglen);
2257 ra[5].buf.len = sizeof(inbuf.siglen);
2258 fds[5] = 0;
2259
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302260 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002261 ioctl.inv.sc = REMOTE_SCALARS_MAKE(6, 4, 0);
Sathish Ambleyd6300c32017-01-18 09:50:43 -08002262 if (uproc->attrs)
2263 ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 6, 0);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002264 ioctl.inv.pra = ra;
2265 ioctl.fds = fds;
c_mtharue1a5ce12017-10-13 20:47:09 +05302266 ioctl.attrs = NULL;
2267 ioctl.crc = NULL;
2268 VERIFY(err, !(err = fastrpc_internal_invoke(fl,
2269 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2270 if (err)
2271 goto bail;
2272 } else if (init->flags == FASTRPC_INIT_CREATE_STATIC) {
2273 remote_arg_t ra[3];
2274 uint64_t phys = 0;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302275 size_t size = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302276 int fds[3];
2277 struct {
2278 int pgid;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302279 unsigned int namelen;
2280 unsigned int pageslen;
c_mtharue1a5ce12017-10-13 20:47:09 +05302281 } inbuf;
2282
2283 if (!init->filelen)
2284 goto bail;
2285
2286 proc_name = kzalloc(init->filelen, GFP_KERNEL);
2287 VERIFY(err, !IS_ERR_OR_NULL(proc_name));
2288 if (err)
2289 goto bail;
2290 VERIFY(err, 0 == copy_from_user((void *)proc_name,
2291 (void __user *)init->file, init->filelen));
2292 if (err)
2293 goto bail;
2294
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302295 fl->pd = 1;
c_mtharue1a5ce12017-10-13 20:47:09 +05302296 inbuf.pgid = current->tgid;
c_mtharu81a0aa72017-11-07 16:13:21 +05302297 inbuf.namelen = init->filelen;
c_mtharue1a5ce12017-10-13 20:47:09 +05302298 inbuf.pageslen = 0;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302299
2300 if (!strcmp(proc_name, "audiopd")) {
2301 fl->spdname = AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME;
2302 VERIFY(err, !fastrpc_mmap_remove_pdr(fl));
Tharun Kumar Merugu35173342018-02-08 16:13:17 +05302303 if (err)
2304 goto bail;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302305 }
2306
c_mtharue1a5ce12017-10-13 20:47:09 +05302307 if (!me->staticpd_flags) {
2308 inbuf.pageslen = 1;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302309 mutex_lock(&fl->fl_map_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05302310 VERIFY(err, !fastrpc_mmap_create(fl, -1, 0, init->mem,
2311 init->memlen, ADSP_MMAP_REMOTE_HEAP_ADDR,
2312 &mem));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302313 mutex_unlock(&fl->fl_map_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05302314 if (err)
2315 goto bail;
2316 phys = mem->phys;
2317 size = mem->size;
2318 VERIFY(err, !hyp_assign_phys(phys, (uint64_t)size,
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05302319 hlosvm, 1, me->channel[fl->cid].rhvm.vmid,
2320 me->channel[fl->cid].rhvm.vmperm,
2321 me->channel[fl->cid].rhvm.vmcount));
c_mtharue1a5ce12017-10-13 20:47:09 +05302322 if (err) {
2323 pr_err("ADSPRPC: hyp_assign_phys fail err %d",
2324 err);
2325 pr_err("map->phys %llx, map->size %d\n",
2326 phys, (int)size);
2327 goto bail;
2328 }
2329 me->staticpd_flags = 1;
2330 }
2331
2332 ra[0].buf.pv = (void *)&inbuf;
2333 ra[0].buf.len = sizeof(inbuf);
2334 fds[0] = 0;
2335
2336 ra[1].buf.pv = (void *)proc_name;
2337 ra[1].buf.len = inbuf.namelen;
2338 fds[1] = 0;
2339
2340 pages[0].addr = phys;
2341 pages[0].size = size;
2342
2343 ra[2].buf.pv = (void *)pages;
2344 ra[2].buf.len = sizeof(*pages);
2345 fds[2] = 0;
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302346 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
c_mtharue1a5ce12017-10-13 20:47:09 +05302347
2348 ioctl.inv.sc = REMOTE_SCALARS_MAKE(8, 3, 0);
2349 ioctl.inv.pra = ra;
2350 ioctl.fds = NULL;
2351 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002352 ioctl.crc = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002353 VERIFY(err, !(err = fastrpc_internal_invoke(fl,
2354 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2355 if (err)
2356 goto bail;
2357 } else {
2358 err = -ENOTTY;
2359 }
2360bail:
c_mtharud91205a2017-11-07 16:01:06 +05302361 kfree(proc_name);
c_mtharue1a5ce12017-10-13 20:47:09 +05302362 if (err && (init->flags == FASTRPC_INIT_CREATE_STATIC))
2363 me->staticpd_flags = 0;
2364 if (mem && err) {
2365 if (mem->flags == ADSP_MMAP_REMOTE_HEAP_ADDR)
2366 hyp_assign_phys(mem->phys, (uint64_t)mem->size,
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05302367 me->channel[fl->cid].rhvm.vmid,
2368 me->channel[fl->cid].rhvm.vmcount,
2369 hlosvm, hlosvmperm, 1);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302370 mutex_lock(&fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302371 fastrpc_mmap_free(mem, 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302372 mutex_unlock(&fl->fl_map_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05302373 }
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302374 if (file) {
2375 mutex_lock(&fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302376 fastrpc_mmap_free(file, 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302377 mutex_unlock(&fl->fl_map_mutex);
2378 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002379 return err;
2380}
2381
2382static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl)
2383{
2384 int err = 0;
Sathish Ambleybae51902017-07-03 15:00:49 -07002385 struct fastrpc_ioctl_invoke_crc ioctl;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002386 remote_arg_t ra[1];
2387 int tgid = 0;
2388
Sathish Ambley36849af2017-02-02 09:35:55 -08002389 VERIFY(err, fl->cid >= 0 && fl->cid < NUM_CHANNELS);
2390 if (err)
2391 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +05302392 VERIFY(err, fl->apps->channel[fl->cid].chan != NULL);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002393 if (err)
2394 goto bail;
2395 tgid = fl->tgid;
2396 ra[0].buf.pv = (void *)&tgid;
2397 ra[0].buf.len = sizeof(tgid);
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302398 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002399 ioctl.inv.sc = REMOTE_SCALARS_MAKE(1, 1, 0);
2400 ioctl.inv.pra = ra;
c_mtharue1a5ce12017-10-13 20:47:09 +05302401 ioctl.fds = NULL;
2402 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002403 ioctl.crc = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002404 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2405 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2406bail:
2407 return err;
2408}
2409
2410static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302411 uintptr_t va, uint64_t phys,
2412 size_t size, uintptr_t *raddr)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002413{
Sathish Ambleybae51902017-07-03 15:00:49 -07002414 struct fastrpc_ioctl_invoke_crc ioctl;
c_mtharu63ffc012017-11-16 15:26:56 +05302415 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002416 struct smq_phy_page page;
2417 int num = 1;
2418 remote_arg_t ra[3];
2419 int err = 0;
2420 struct {
2421 int pid;
2422 uint32_t flags;
2423 uintptr_t vaddrin;
2424 int num;
2425 } inargs;
2426 struct {
2427 uintptr_t vaddrout;
2428 } routargs;
2429
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302430 inargs.pid = fl->tgid;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302431 inargs.vaddrin = (uintptr_t)va;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002432 inargs.flags = flags;
2433 inargs.num = fl->apps->compat ? num * sizeof(page) : num;
2434 ra[0].buf.pv = (void *)&inargs;
2435 ra[0].buf.len = sizeof(inargs);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302436 page.addr = phys;
2437 page.size = size;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002438 ra[1].buf.pv = (void *)&page;
2439 ra[1].buf.len = num * sizeof(page);
2440
2441 ra[2].buf.pv = (void *)&routargs;
2442 ra[2].buf.len = sizeof(routargs);
2443
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302444 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002445 if (fl->apps->compat)
2446 ioctl.inv.sc = REMOTE_SCALARS_MAKE(4, 2, 1);
2447 else
2448 ioctl.inv.sc = REMOTE_SCALARS_MAKE(2, 2, 1);
2449 ioctl.inv.pra = ra;
c_mtharue1a5ce12017-10-13 20:47:09 +05302450 ioctl.fds = NULL;
2451 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002452 ioctl.crc = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002453 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2454 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302455 *raddr = (uintptr_t)routargs.vaddrout;
c_mtharue1a5ce12017-10-13 20:47:09 +05302456 if (err)
2457 goto bail;
2458 if (flags == ADSP_MMAP_HEAP_ADDR) {
2459 struct scm_desc desc = {0};
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002460
c_mtharue1a5ce12017-10-13 20:47:09 +05302461 desc.args[0] = TZ_PIL_AUTH_QDSP6_PROC;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302462 desc.args[1] = phys;
2463 desc.args[2] = size;
c_mtharue1a5ce12017-10-13 20:47:09 +05302464 desc.arginfo = SCM_ARGS(3);
2465 err = scm_call2(SCM_SIP_FNID(SCM_SVC_PIL,
2466 TZ_PIL_PROTECT_MEM_SUBSYS_ID), &desc);
2467 } else if (flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302468 VERIFY(err, !hyp_assign_phys(phys, (uint64_t)size,
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05302469 hlosvm, 1, me->channel[fl->cid].rhvm.vmid,
2470 me->channel[fl->cid].rhvm.vmperm,
2471 me->channel[fl->cid].rhvm.vmcount));
c_mtharue1a5ce12017-10-13 20:47:09 +05302472 if (err)
2473 goto bail;
2474 }
2475bail:
2476 return err;
2477}
2478
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302479static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl, uint64_t phys,
2480 size_t size, uint32_t flags)
c_mtharue1a5ce12017-10-13 20:47:09 +05302481{
2482 int err = 0;
c_mtharu63ffc012017-11-16 15:26:56 +05302483 struct fastrpc_apps *me = &gfa;
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302484 int tgid = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302485 int destVM[1] = {VMID_HLOS};
2486 int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
2487
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302488 if (flags == ADSP_MMAP_HEAP_ADDR) {
c_mtharue1a5ce12017-10-13 20:47:09 +05302489 struct fastrpc_ioctl_invoke_crc ioctl;
2490 struct scm_desc desc = {0};
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302491 remote_arg_t ra[2];
2492
c_mtharue1a5ce12017-10-13 20:47:09 +05302493 struct {
2494 uint8_t skey;
2495 } routargs;
2496
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302497 if (fl == NULL)
2498 goto bail;
2499 tgid = fl->tgid;
2500 ra[0].buf.pv = (void *)&tgid;
2501 ra[0].buf.len = sizeof(tgid);
2502 ra[1].buf.pv = (void *)&routargs;
2503 ra[1].buf.len = sizeof(routargs);
c_mtharue1a5ce12017-10-13 20:47:09 +05302504
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302505 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302506 ioctl.inv.sc = REMOTE_SCALARS_MAKE(9, 1, 1);
c_mtharue1a5ce12017-10-13 20:47:09 +05302507 ioctl.inv.pra = ra;
2508 ioctl.fds = NULL;
2509 ioctl.attrs = NULL;
2510 ioctl.crc = NULL;
Tharun Kumar Merugu72c90252019-08-29 18:36:08 +05302511
c_mtharue1a5ce12017-10-13 20:47:09 +05302512
2513 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2514 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
Mohammed Nayeem Ur Rahman80f45dc2019-09-23 19:35:19 +05302515 if (err == AEE_EUNSUPPORTED) {
2516 remote_arg_t ra[1];
2517
2518 pr_warn("ADSPRPC:Failed to get security key with updated remote call, falling back to older method");
2519 ra[0].buf.pv = (void *)&routargs;
2520 ra[0].buf.len = sizeof(routargs);
2521 ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 0, 1);
2522 ioctl.inv.pra = ra;
2523 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2524 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
2525 }
c_mtharue1a5ce12017-10-13 20:47:09 +05302526 if (err)
2527 goto bail;
Mohammed Nayeem Ur Rahman80f45dc2019-09-23 19:35:19 +05302528
c_mtharue1a5ce12017-10-13 20:47:09 +05302529 desc.args[0] = TZ_PIL_AUTH_QDSP6_PROC;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302530 desc.args[1] = phys;
2531 desc.args[2] = size;
c_mtharue1a5ce12017-10-13 20:47:09 +05302532 desc.args[3] = routargs.skey;
2533 desc.arginfo = SCM_ARGS(4);
2534 err = scm_call2(SCM_SIP_FNID(SCM_SVC_PIL,
2535 TZ_PIL_CLEAR_PROTECT_MEM_SUBSYS_ID), &desc);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302536 } else if (flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
2537 VERIFY(err, !hyp_assign_phys(phys, (uint64_t)size,
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05302538 me->channel[fl->cid].rhvm.vmid,
2539 me->channel[fl->cid].rhvm.vmcount,
2540 destVM, destVMperm, 1));
c_mtharue1a5ce12017-10-13 20:47:09 +05302541 if (err)
2542 goto bail;
2543 }
2544
2545bail:
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002546 return err;
2547}
2548
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302549static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl, uintptr_t raddr,
2550 uint64_t phys, size_t size, uint32_t flags)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002551{
Sathish Ambleybae51902017-07-03 15:00:49 -07002552 struct fastrpc_ioctl_invoke_crc ioctl;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002553 remote_arg_t ra[1];
2554 int err = 0;
2555 struct {
2556 int pid;
2557 uintptr_t vaddrout;
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302558 size_t size;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002559 } inargs;
2560
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05302561 inargs.pid = fl->tgid;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302562 inargs.size = size;
2563 inargs.vaddrout = raddr;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002564 ra[0].buf.pv = (void *)&inargs;
2565 ra[0].buf.len = sizeof(inargs);
2566
Tharun Kumar Merugucc2e11e2019-02-02 01:22:47 +05302567 ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002568 if (fl->apps->compat)
2569 ioctl.inv.sc = REMOTE_SCALARS_MAKE(5, 1, 0);
2570 else
2571 ioctl.inv.sc = REMOTE_SCALARS_MAKE(3, 1, 0);
2572 ioctl.inv.pra = ra;
c_mtharue1a5ce12017-10-13 20:47:09 +05302573 ioctl.fds = NULL;
2574 ioctl.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07002575 ioctl.crc = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002576 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
2577 FASTRPC_MODE_PARALLEL, 1, &ioctl)));
c_mtharue1a5ce12017-10-13 20:47:09 +05302578 if (err)
2579 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302580 if (flags == ADSP_MMAP_HEAP_ADDR ||
2581 flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
2582 VERIFY(err, !fastrpc_munmap_on_dsp_rh(fl, phys, size, flags));
c_mtharue1a5ce12017-10-13 20:47:09 +05302583 if (err)
2584 goto bail;
2585 }
2586bail:
2587 return err;
2588}
2589
2590static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl)
2591{
2592 struct fastrpc_mmap *match = NULL, *map = NULL;
2593 struct hlist_node *n = NULL;
2594 int err = 0, ret = 0;
2595 struct fastrpc_apps *me = &gfa;
2596 struct ramdump_segment *ramdump_segments_rh = NULL;
2597
2598 do {
2599 match = NULL;
2600 spin_lock(&me->hlock);
2601 hlist_for_each_entry_safe(map, n, &me->maps, hn) {
2602 match = map;
2603 hlist_del_init(&map->hn);
2604 break;
2605 }
2606 spin_unlock(&me->hlock);
2607
2608 if (match) {
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302609 VERIFY(err, !fastrpc_munmap_on_dsp_rh(fl, match->phys,
2610 match->size, match->flags));
c_mtharue1a5ce12017-10-13 20:47:09 +05302611 if (err)
2612 goto bail;
2613 if (me->channel[0].ramdumpenabled) {
2614 ramdump_segments_rh = kcalloc(1,
2615 sizeof(struct ramdump_segment), GFP_KERNEL);
2616 if (ramdump_segments_rh) {
2617 ramdump_segments_rh->address =
2618 match->phys;
2619 ramdump_segments_rh->size = match->size;
2620 ret = do_elf_ramdump(
2621 me->channel[0].remoteheap_ramdump_dev,
2622 ramdump_segments_rh, 1);
2623 if (ret < 0)
2624 pr_err("ADSPRPC: unable to dump heap");
2625 kfree(ramdump_segments_rh);
2626 }
2627 }
c_mtharu7bd6a422017-10-17 18:15:37 +05302628 fastrpc_mmap_free(match, 0);
c_mtharue1a5ce12017-10-13 20:47:09 +05302629 }
2630 } while (match);
2631bail:
2632 if (err && match)
2633 fastrpc_mmap_add(match);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002634 return err;
2635}
2636
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05302637static int fastrpc_mmap_remove_pdr(struct fastrpc_file *fl)
2638{
2639 struct fastrpc_apps *me = &gfa;
2640 int session = 0, err = 0;
2641
2642 VERIFY(err, !fastrpc_get_adsp_session(
2643 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, &session));
2644 if (err)
2645 goto bail;
2646 if (me->channel[fl->cid].spd[session].pdrcount !=
2647 me->channel[fl->cid].spd[session].prevpdrcount) {
2648 if (fastrpc_mmap_remove_ssr(fl))
2649 pr_err("ADSPRPC: SSR: Failed to unmap remote heap\n");
2650 me->channel[fl->cid].spd[session].prevpdrcount =
2651 me->channel[fl->cid].spd[session].pdrcount;
2652 }
2653 if (!me->channel[fl->cid].spd[session].ispdup) {
2654 VERIFY(err, 0);
2655 if (err) {
2656 err = -ENOTCONN;
2657 goto bail;
2658 }
2659 }
2660bail:
2661 return err;
2662}
2663
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002664static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
Tharun Kumar Merugufb51f942017-12-07 10:32:15 +05302665 size_t len, struct fastrpc_mmap **ppmap);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002666
2667static void fastrpc_mmap_add(struct fastrpc_mmap *map);
2668
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05302669static inline void get_fastrpc_ioctl_mmap_64(
2670 struct fastrpc_ioctl_mmap_64 *mmap64,
2671 struct fastrpc_ioctl_mmap *immap)
2672{
2673 immap->fd = mmap64->fd;
2674 immap->flags = mmap64->flags;
2675 immap->vaddrin = (uintptr_t)mmap64->vaddrin;
2676 immap->size = mmap64->size;
2677}
2678
2679static inline void put_fastrpc_ioctl_mmap_64(
2680 struct fastrpc_ioctl_mmap_64 *mmap64,
2681 struct fastrpc_ioctl_mmap *immap)
2682{
2683 mmap64->vaddrout = (uint64_t)immap->vaddrout;
2684}
2685
2686static inline void get_fastrpc_ioctl_munmap_64(
2687 struct fastrpc_ioctl_munmap_64 *munmap64,
2688 struct fastrpc_ioctl_munmap *imunmap)
2689{
2690 imunmap->vaddrout = (uintptr_t)munmap64->vaddrout;
2691 imunmap->size = munmap64->size;
2692}
2693
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002694static int fastrpc_internal_munmap(struct fastrpc_file *fl,
2695 struct fastrpc_ioctl_munmap *ud)
2696{
2697 int err = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05302698 struct fastrpc_mmap *map = NULL;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302699 struct fastrpc_buf *rbuf = NULL, *free = NULL;
2700 struct hlist_node *n;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002701
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302702 mutex_lock(&fl->map_mutex);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302703
2704 spin_lock(&fl->hlock);
2705 hlist_for_each_entry_safe(rbuf, n, &fl->remote_bufs, hn_rem) {
2706 if (rbuf->raddr && (rbuf->flags == ADSP_MMAP_ADD_PAGES)) {
2707 if ((rbuf->raddr == ud->vaddrout) &&
2708 (rbuf->size == ud->size)) {
2709 free = rbuf;
2710 break;
2711 }
2712 }
2713 }
2714 spin_unlock(&fl->hlock);
2715
2716 if (free) {
2717 VERIFY(err, !fastrpc_munmap_on_dsp(fl, free->raddr,
2718 free->phys, free->size, free->flags));
2719 if (err)
2720 goto bail;
2721 fastrpc_buf_free(rbuf, 0);
2722 mutex_unlock(&fl->map_mutex);
2723 return err;
2724 }
2725
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302726 mutex_lock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002727 VERIFY(err, !fastrpc_mmap_remove(fl, ud->vaddrout, ud->size, &map));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302728 mutex_unlock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002729 if (err)
2730 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302731 VERIFY(err, !fastrpc_munmap_on_dsp(fl, map->raddr,
2732 map->phys, map->size, map->flags));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002733 if (err)
2734 goto bail;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302735 mutex_lock(&fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302736 fastrpc_mmap_free(map, 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302737 mutex_unlock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002738bail:
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302739 if (err && map) {
2740 mutex_lock(&fl->fl_map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002741 fastrpc_mmap_add(map);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302742 mutex_unlock(&fl->fl_map_mutex);
2743 }
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302744 mutex_unlock(&fl->map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002745 return err;
2746}
2747
c_mtharu7bd6a422017-10-17 18:15:37 +05302748static int fastrpc_internal_munmap_fd(struct fastrpc_file *fl,
2749 struct fastrpc_ioctl_munmap_fd *ud) {
2750 int err = 0;
2751 struct fastrpc_mmap *map = NULL;
2752
2753 VERIFY(err, (fl && ud));
2754 if (err)
2755 goto bail;
Mohammed Nayeem Ur Rahmanfc548a52020-01-07 17:07:55 +05302756 mutex_lock(&fl->map_mutex);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302757 mutex_lock(&fl->fl_map_mutex);
Tharun Kumar Merugu09fc6152018-02-16 13:13:12 +05302758 if (fastrpc_mmap_find(fl, ud->fd, ud->va, ud->len, 0, 0, &map)) {
2759 pr_err("adsprpc: mapping not found to unmap %d va %llx %x\n",
c_mtharu7bd6a422017-10-17 18:15:37 +05302760 ud->fd, (unsigned long long)ud->va,
2761 (unsigned int)ud->len);
2762 err = -1;
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302763 mutex_unlock(&fl->fl_map_mutex);
Mohammed Nayeem Ur Rahmanfc548a52020-01-07 17:07:55 +05302764 mutex_unlock(&fl->map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302765 goto bail;
2766 }
2767 if (map)
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302768 fastrpc_mmap_free(map, 0);
2769 mutex_unlock(&fl->fl_map_mutex);
Mohammed Nayeem Ur Rahmanfc548a52020-01-07 17:07:55 +05302770 mutex_unlock(&fl->map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302771bail:
2772 return err;
2773}
2774
2775
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002776static int fastrpc_internal_mmap(struct fastrpc_file *fl,
2777 struct fastrpc_ioctl_mmap *ud)
2778{
2779
c_mtharue1a5ce12017-10-13 20:47:09 +05302780 struct fastrpc_mmap *map = NULL;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302781 struct fastrpc_buf *rbuf = NULL;
2782 unsigned long dma_attr = 0;
2783 uintptr_t raddr = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002784 int err = 0;
2785
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302786 mutex_lock(&fl->map_mutex);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302787 if (ud->flags == ADSP_MMAP_ADD_PAGES) {
2788 if (ud->vaddrin) {
2789 err = -EINVAL;
2790 pr_err("adsprpc: %s: %s: ERROR: adding user allocated pages is not supported\n",
2791 current->comm, __func__);
2792 goto bail;
2793 }
2794 dma_attr = DMA_ATTR_EXEC_MAPPING |
2795 DMA_ATTR_NO_KERNEL_MAPPING |
2796 DMA_ATTR_FORCE_NON_COHERENT;
2797 err = fastrpc_buf_alloc(fl, ud->size, dma_attr, ud->flags,
2798 1, &rbuf);
2799 if (err)
2800 goto bail;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +05302801 err = fastrpc_mmap_on_dsp(fl, ud->flags, 0,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302802 rbuf->phys, rbuf->size, &raddr);
2803 if (err)
2804 goto bail;
2805 rbuf->raddr = raddr;
2806 } else {
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +05302807
2808 uintptr_t va_to_dsp;
2809
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302810 mutex_lock(&fl->fl_map_mutex);
2811 if (!fastrpc_mmap_find(fl, ud->fd, (uintptr_t)ud->vaddrin,
2812 ud->size, ud->flags, 1, &map)) {
Mohammed Nayeem Ur Rahmanaf5f6102019-10-09 13:36:52 +05302813 ud->vaddrout = map->raddr;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302814 mutex_unlock(&fl->fl_map_mutex);
2815 mutex_unlock(&fl->map_mutex);
2816 return 0;
2817 }
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +05302818
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302819 VERIFY(err, !fastrpc_mmap_create(fl, ud->fd, 0,
2820 (uintptr_t)ud->vaddrin, ud->size,
2821 ud->flags, &map));
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302822 mutex_unlock(&fl->fl_map_mutex);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302823 if (err)
2824 goto bail;
Tharun Kumar Merugu0d0b69e2018-09-14 22:30:58 +05302825
2826 if (ud->flags == ADSP_MMAP_HEAP_ADDR ||
2827 ud->flags == ADSP_MMAP_REMOTE_HEAP_ADDR)
2828 va_to_dsp = 0;
2829 else
2830 va_to_dsp = (uintptr_t)map->va;
2831 VERIFY(err, 0 == fastrpc_mmap_on_dsp(fl, ud->flags, va_to_dsp,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05302832 map->phys, map->size, &raddr));
2833 if (err)
2834 goto bail;
2835 map->raddr = raddr;
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302836 }
Mohammed Nayeem Ur Rahman3ac5d322018-09-24 13:54:08 +05302837 ud->vaddrout = raddr;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002838 bail:
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302839 if (err && map) {
2840 mutex_lock(&fl->fl_map_mutex);
c_mtharu7bd6a422017-10-17 18:15:37 +05302841 fastrpc_mmap_free(map, 0);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05302842 mutex_unlock(&fl->fl_map_mutex);
2843 }
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05302844 mutex_unlock(&fl->map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002845 return err;
2846}
2847
2848static void fastrpc_channel_close(struct kref *kref)
2849{
2850 struct fastrpc_apps *me = &gfa;
2851 struct fastrpc_channel_ctx *ctx;
2852 int cid;
2853
2854 ctx = container_of(kref, struct fastrpc_channel_ctx, kref);
2855 cid = ctx - &gcinfo[0];
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05302856 if (me->glink) {
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05302857 fastrpc_glink_close(ctx->chan, cid);
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05302858 ctx->chan = NULL;
2859 }
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302860 mutex_unlock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002861 pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name,
2862 MAJOR(me->dev_no), cid);
2863}
2864
2865static void fastrpc_context_list_dtor(struct fastrpc_file *fl);
2866
2867static int fastrpc_session_alloc_locked(struct fastrpc_channel_ctx *chan,
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302868 int secure, int sharedcb, struct fastrpc_session_ctx **session)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002869{
2870 struct fastrpc_apps *me = &gfa;
2871 int idx = 0, err = 0;
2872
2873 if (chan->sesscount) {
2874 for (idx = 0; idx < chan->sesscount; ++idx) {
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302875 if ((sharedcb && chan->session[idx].smmu.sharedcb) ||
2876 (!chan->session[idx].used &&
2877 chan->session[idx].smmu.secure
2878 == secure && !sharedcb)) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002879 chan->session[idx].used = 1;
2880 break;
2881 }
2882 }
2883 VERIFY(err, idx < chan->sesscount);
2884 if (err)
2885 goto bail;
2886 chan->session[idx].smmu.faults = 0;
2887 } else {
2888 VERIFY(err, me->dev != NULL);
2889 if (err)
2890 goto bail;
2891 chan->session[0].dev = me->dev;
c_mtharue1a5ce12017-10-13 20:47:09 +05302892 chan->session[0].smmu.dev = me->dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002893 }
2894
2895 *session = &chan->session[idx];
2896 bail:
2897 return err;
2898}
2899
c_mtharue1a5ce12017-10-13 20:47:09 +05302900static bool fastrpc_glink_notify_rx_intent_req(void *h, const void *priv,
2901 size_t size)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002902{
2903 if (glink_queue_rx_intent(h, NULL, size))
2904 return false;
2905 return true;
2906}
2907
c_mtharue1a5ce12017-10-13 20:47:09 +05302908static void fastrpc_glink_notify_tx_done(void *handle, const void *priv,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002909 const void *pkt_priv, const void *ptr)
2910{
2911}
2912
c_mtharue1a5ce12017-10-13 20:47:09 +05302913static void fastrpc_glink_notify_rx(void *handle, const void *priv,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002914 const void *pkt_priv, const void *ptr, size_t size)
2915{
2916 struct smq_invoke_rsp *rsp = (struct smq_invoke_rsp *)ptr;
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302917 struct fastrpc_apps *me = &gfa;
2918 uint32_t index;
c_mtharufdac6892017-10-12 13:09:01 +05302919 int err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002920
c_mtharufdac6892017-10-12 13:09:01 +05302921 VERIFY(err, (rsp && size >= sizeof(*rsp)));
2922 if (err)
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05302923 goto bail;
2924
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302925 index = (uint32_t)((rsp->ctx & FASTRPC_CTXID_MASK) >> 4);
2926 VERIFY(err, index < FASTRPC_CTX_MAX);
c_mtharufdac6892017-10-12 13:09:01 +05302927 if (err)
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05302928 goto bail;
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05302929
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302930 VERIFY(err, !IS_ERR_OR_NULL(me->ctxtable[index]));
2931 if (err)
2932 goto bail;
2933
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302934 VERIFY(err, ((me->ctxtable[index]->ctxid == (rsp->ctx & ~3)) &&
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302935 me->ctxtable[index]->magic == FASTRPC_CTX_MAGIC));
2936 if (err)
2937 goto bail;
2938
Mohammed Nayeem Ur Rahman32ba95d2019-07-26 17:31:37 +05302939 me->ctxtable[index]->handle = handle;
2940 me->ctxtable[index]->ptr = ptr;
2941
Tharun Kumar Merugu9c908aa2018-02-06 12:03:48 +05302942 context_notify_user(me->ctxtable[index], rsp->retval);
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05302943bail:
c_mtharufdac6892017-10-12 13:09:01 +05302944 if (err)
2945 pr_err("adsprpc: invalid response or context\n");
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002946}
2947
c_mtharue1a5ce12017-10-13 20:47:09 +05302948static void fastrpc_glink_notify_state(void *handle, const void *priv,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002949 unsigned int event)
2950{
2951 struct fastrpc_apps *me = &gfa;
2952 int cid = (int)(uintptr_t)priv;
2953 struct fastrpc_glink_info *link;
2954
2955 if (cid < 0 || cid >= NUM_CHANNELS)
2956 return;
2957 link = &me->channel[cid].link;
2958 switch (event) {
2959 case GLINK_CONNECTED:
2960 link->port_state = FASTRPC_LINK_CONNECTED;
Tharun Kumar Merugu53a8ec92017-07-14 15:52:49 +05302961 complete(&me->channel[cid].workport);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002962 break;
2963 case GLINK_LOCAL_DISCONNECTED:
2964 link->port_state = FASTRPC_LINK_DISCONNECTED;
2965 break;
2966 case GLINK_REMOTE_DISCONNECTED:
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002967 break;
2968 default:
2969 break;
2970 }
2971}
2972
2973static int fastrpc_session_alloc(struct fastrpc_channel_ctx *chan, int secure,
2974 struct fastrpc_session_ctx **session)
2975{
2976 int err = 0;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302977 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002978
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302979 mutex_lock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002980 if (!*session)
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05302981 err = fastrpc_session_alloc_locked(chan, secure, 0, session);
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302982 mutex_unlock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002983 return err;
2984}
2985
2986static void fastrpc_session_free(struct fastrpc_channel_ctx *chan,
2987 struct fastrpc_session_ctx *session)
2988{
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302989 struct fastrpc_apps *me = &gfa;
2990
2991 mutex_lock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002992 session->used = 0;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05302993 mutex_unlock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07002994}
2995
2996static int fastrpc_file_free(struct fastrpc_file *fl)
2997{
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05302998 struct hlist_node *n = NULL;
Tharun Kumar Merugu3e966762018-04-04 10:56:44 +05302999 struct fastrpc_mmap *map = NULL, *lmap = NULL;
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303000 struct fastrpc_perf *perf = NULL, *fperf = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003001 int cid;
3002
3003 if (!fl)
3004 return 0;
3005 cid = fl->cid;
3006
Tharun Kumar Merugu622d8712017-09-15 15:30:06 +05303007 (void)fastrpc_release_current_dsp_process(fl);
3008
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003009 spin_lock(&fl->apps->hlock);
3010 hlist_del_init(&fl->hn);
3011 spin_unlock(&fl->apps->hlock);
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303012 kfree(fl->debug_buf);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003013
Sathish Ambleyd7fbcbb2017-03-08 10:55:48 -08003014 if (!fl->sctx) {
3015 kfree(fl);
3016 return 0;
3017 }
tharun kumar9f899ea2017-07-03 17:07:03 +05303018 spin_lock(&fl->hlock);
3019 fl->file_close = 1;
3020 spin_unlock(&fl->hlock);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303021 if (!IS_ERR_OR_NULL(fl->init_mem))
3022 fastrpc_buf_free(fl->init_mem, 0);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003023 fastrpc_context_list_dtor(fl);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303024 fastrpc_cached_buf_list_free(fl);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303025 mutex_lock(&fl->fl_map_mutex);
Tharun Kumar Merugu3e966762018-04-04 10:56:44 +05303026 do {
3027 lmap = NULL;
3028 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
3029 hlist_del_init(&map->hn);
3030 lmap = map;
3031 break;
3032 }
3033 fastrpc_mmap_free(lmap, 1);
3034 } while (lmap);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303035 mutex_unlock(&fl->fl_map_mutex);
Tharun Kumar Merugu35173342018-02-08 16:13:17 +05303036 if (fl->refcount && (fl->ssrcount == fl->apps->channel[cid].ssrcount))
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003037 kref_put_mutex(&fl->apps->channel[cid].kref,
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303038 fastrpc_channel_close, &fl->apps->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003039 if (fl->sctx)
3040 fastrpc_session_free(&fl->apps->channel[cid], fl->sctx);
3041 if (fl->secsctx)
3042 fastrpc_session_free(&fl->apps->channel[cid], fl->secsctx);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303043
3044 mutex_lock(&fl->perf_mutex);
3045 do {
3046 struct hlist_node *pn = NULL;
3047
3048 fperf = NULL;
3049 hlist_for_each_entry_safe(perf, pn, &fl->perf, hn) {
3050 hlist_del_init(&perf->hn);
3051 fperf = perf;
3052 break;
3053 }
3054 kfree(fperf);
3055 } while (fperf);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303056 fastrpc_remote_buf_list_free(fl);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303057 mutex_unlock(&fl->perf_mutex);
3058 mutex_destroy(&fl->perf_mutex);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303059 mutex_destroy(&fl->fl_map_mutex);
Tharun Kumar Merugu8714e642018-05-17 15:21:08 +05303060 mutex_destroy(&fl->map_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003061 kfree(fl);
3062 return 0;
3063}
3064
3065static int fastrpc_device_release(struct inode *inode, struct file *file)
3066{
3067 struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
3068
3069 if (fl) {
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303070 if (fl->qos_request && pm_qos_request_active(&fl->pm_qos_req))
3071 pm_qos_remove_request(&fl->pm_qos_req);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003072 if (fl->debugfs_file != NULL)
3073 debugfs_remove(fl->debugfs_file);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003074 fastrpc_file_free(fl);
c_mtharue1a5ce12017-10-13 20:47:09 +05303075 file->private_data = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003076 }
3077 return 0;
3078}
3079
3080static void fastrpc_link_state_handler(struct glink_link_state_cb_info *cb_info,
3081 void *priv)
3082{
3083 struct fastrpc_apps *me = &gfa;
3084 int cid = (int)((uintptr_t)priv);
3085 struct fastrpc_glink_info *link;
3086
3087 if (cid < 0 || cid >= NUM_CHANNELS)
3088 return;
3089
3090 link = &me->channel[cid].link;
3091 switch (cb_info->link_state) {
3092 case GLINK_LINK_STATE_UP:
3093 link->link_state = FASTRPC_LINK_STATE_UP;
3094 complete(&me->channel[cid].work);
3095 break;
3096 case GLINK_LINK_STATE_DOWN:
3097 link->link_state = FASTRPC_LINK_STATE_DOWN;
3098 break;
3099 default:
3100 pr_err("adsprpc: unknown link state %d\n", cb_info->link_state);
3101 break;
3102 }
3103}
3104
3105static int fastrpc_glink_register(int cid, struct fastrpc_apps *me)
3106{
3107 int err = 0;
3108 struct fastrpc_glink_info *link;
3109
3110 VERIFY(err, (cid >= 0 && cid < NUM_CHANNELS));
3111 if (err)
3112 goto bail;
3113
3114 link = &me->channel[cid].link;
3115 if (link->link_notify_handle != NULL)
3116 goto bail;
3117
3118 link->link_info.glink_link_state_notif_cb = fastrpc_link_state_handler;
3119 link->link_notify_handle = glink_register_link_state_cb(
3120 &link->link_info,
3121 (void *)((uintptr_t)cid));
3122 VERIFY(err, !IS_ERR_OR_NULL(me->channel[cid].link.link_notify_handle));
3123 if (err) {
3124 link->link_notify_handle = NULL;
3125 goto bail;
3126 }
3127 VERIFY(err, wait_for_completion_timeout(&me->channel[cid].work,
3128 RPC_TIMEOUT));
3129bail:
3130 return err;
3131}
3132
3133static void fastrpc_glink_close(void *chan, int cid)
3134{
3135 int err = 0;
3136 struct fastrpc_glink_info *link;
3137
3138 VERIFY(err, (cid >= 0 && cid < NUM_CHANNELS));
3139 if (err)
3140 return;
3141 link = &gfa.channel[cid].link;
3142
c_mtharu314a4202017-11-15 22:09:17 +05303143 if (link->port_state == FASTRPC_LINK_CONNECTED ||
3144 link->port_state == FASTRPC_LINK_REMOTE_DISCONNECTING) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003145 link->port_state = FASTRPC_LINK_DISCONNECTING;
3146 glink_close(chan);
3147 }
3148}
3149
3150static int fastrpc_glink_open(int cid)
3151{
3152 int err = 0;
3153 void *handle = NULL;
3154 struct fastrpc_apps *me = &gfa;
3155 struct glink_open_config *cfg;
3156 struct fastrpc_glink_info *link;
3157
3158 VERIFY(err, (cid >= 0 && cid < NUM_CHANNELS));
3159 if (err)
3160 goto bail;
3161 link = &me->channel[cid].link;
3162 cfg = &me->channel[cid].link.cfg;
3163 VERIFY(err, (link->link_state == FASTRPC_LINK_STATE_UP));
3164 if (err)
3165 goto bail;
3166
Tharun Kumar Meruguca0db5262017-05-10 12:53:12 +05303167 VERIFY(err, (link->port_state == FASTRPC_LINK_DISCONNECTED));
3168 if (err)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003169 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003170
3171 link->port_state = FASTRPC_LINK_CONNECTING;
3172 cfg->priv = (void *)(uintptr_t)cid;
3173 cfg->edge = gcinfo[cid].link.link_info.edge;
3174 cfg->transport = gcinfo[cid].link.link_info.transport;
3175 cfg->name = FASTRPC_GLINK_GUID;
3176 cfg->notify_rx = fastrpc_glink_notify_rx;
3177 cfg->notify_tx_done = fastrpc_glink_notify_tx_done;
3178 cfg->notify_state = fastrpc_glink_notify_state;
3179 cfg->notify_rx_intent_req = fastrpc_glink_notify_rx_intent_req;
3180 handle = glink_open(cfg);
3181 VERIFY(err, !IS_ERR_OR_NULL(handle));
c_mtharu6e1d26b2017-10-09 16:05:24 +05303182 if (err) {
3183 if (link->port_state == FASTRPC_LINK_CONNECTING)
3184 link->port_state = FASTRPC_LINK_DISCONNECTED;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003185 goto bail;
c_mtharu6e1d26b2017-10-09 16:05:24 +05303186 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003187 me->channel[cid].chan = handle;
3188bail:
3189 return err;
3190}
3191
Sathish Ambley1ca68232017-01-19 10:32:55 -08003192static int fastrpc_debugfs_open(struct inode *inode, struct file *filp)
3193{
3194 filp->private_data = inode->i_private;
3195 return 0;
3196}
3197
3198static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
3199 size_t count, loff_t *position)
3200{
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303201 struct fastrpc_apps *me = &gfa;
Sathish Ambley1ca68232017-01-19 10:32:55 -08003202 struct fastrpc_file *fl = filp->private_data;
3203 struct hlist_node *n;
c_mtharue1a5ce12017-10-13 20:47:09 +05303204 struct fastrpc_buf *buf = NULL;
3205 struct fastrpc_mmap *map = NULL;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303206 struct fastrpc_mmap *gmaps = NULL;
c_mtharue1a5ce12017-10-13 20:47:09 +05303207 struct smq_invoke_ctx *ictx = NULL;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303208 struct fastrpc_channel_ctx *chan = NULL;
Sathish Ambley1ca68232017-01-19 10:32:55 -08003209 unsigned int len = 0;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303210 int i, j, sess_used = 0, ret = 0;
Sathish Ambley1ca68232017-01-19 10:32:55 -08003211 char *fileinfo = NULL;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303212 char single_line[UL_SIZE] = "----------------";
3213 char title[UL_SIZE] = "=========================";
Sathish Ambley1ca68232017-01-19 10:32:55 -08003214
3215 fileinfo = kzalloc(DEBUGFS_SIZE, GFP_KERNEL);
3216 if (!fileinfo)
3217 goto bail;
3218 if (fl == NULL) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303219 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3220 "\n%s %s %s\n", title, " CHANNEL INFO ", title);
3221 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3222 "%-8s|%-9s|%-9s|%-14s|%-9s|%-13s\n",
3223 "susbsys", "refcount", "sesscount", "issubsystemup",
3224 "ssrcount", "session_used");
3225 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3226 "-%s%s%s%s-\n", single_line, single_line,
3227 single_line, single_line);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003228 for (i = 0; i < NUM_CHANNELS; i++) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303229 sess_used = 0;
Sathish Ambley1ca68232017-01-19 10:32:55 -08003230 chan = &gcinfo[i];
3231 len += scnprintf(fileinfo + len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303232 DEBUGFS_SIZE - len, "%-8s", chan->subsys);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003233 len += scnprintf(fileinfo + len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303234 DEBUGFS_SIZE - len, "|%-9d",
3235 chan->kref.refcount.counter);
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303236 len += scnprintf(fileinfo + len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303237 DEBUGFS_SIZE - len, "|%-9d",
3238 chan->sesscount);
3239 len += scnprintf(fileinfo + len,
3240 DEBUGFS_SIZE - len, "|%-14d",
3241 chan->issubsystemup);
3242 len += scnprintf(fileinfo + len,
3243 DEBUGFS_SIZE - len, "|%-9d",
3244 chan->ssrcount);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003245 for (j = 0; j < chan->sesscount; j++) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303246 sess_used += chan->session[j].used;
3247 }
3248 len += scnprintf(fileinfo + len,
3249 DEBUGFS_SIZE - len, "|%-13d\n", sess_used);
3250
3251 }
3252 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3253 "\n%s%s%s\n", "=============",
3254 " CMA HEAP ", "==============");
3255 len += scnprintf(fileinfo + len,
3256 DEBUGFS_SIZE - len, "%-20s|%-20s\n", "addr", "size");
3257 len += scnprintf(fileinfo + len,
3258 DEBUGFS_SIZE - len, "--%s%s---\n",
3259 single_line, single_line);
3260 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3261 "0x%-18llX", me->range.addr);
3262 len += scnprintf(fileinfo + len,
3263 DEBUGFS_SIZE - len, "|0x%-18llX\n", me->range.size);
3264 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3265 "\n==========%s %s %s===========\n",
3266 title, " GMAPS ", title);
3267 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3268 "%-20s|%-20s|%-20s|%-20s\n",
3269 "fd", "phys", "size", "va");
3270 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3271 "%s%s%s%s%s\n", single_line, single_line,
3272 single_line, single_line, single_line);
3273 hlist_for_each_entry_safe(gmaps, n, &me->maps, hn) {
3274 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3275 "%-20d|0x%-18llX|0x%-18X|0x%-20lX\n\n",
3276 gmaps->fd, gmaps->phys,
3277 (uint32_t)gmaps->size,
3278 gmaps->va);
3279 }
3280 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3281 "%-20s|%-20s|%-20s|%-20s\n",
3282 "len", "refs", "raddr", "flags");
3283 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3284 "%s%s%s%s%s\n", single_line, single_line,
3285 single_line, single_line, single_line);
3286 hlist_for_each_entry_safe(gmaps, n, &me->maps, hn) {
3287 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3288 "0x%-18X|%-20d|%-20lu|%-20u\n",
3289 (uint32_t)gmaps->len, gmaps->refs,
3290 gmaps->raddr, gmaps->flags);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003291 }
3292 } else {
3293 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303294 "\n%s %13s %d\n", "cid", ":", fl->cid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003295 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303296 "%s %12s %d\n", "tgid", ":", fl->tgid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003297 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303298 "%s %7s %d\n", "sessionid", ":", fl->sessionid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003299 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303300 "%s %8s %d\n", "ssrcount", ":", fl->ssrcount);
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303301 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303302 "%s %8s %d\n", "refcount", ":", fl->refcount);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003303 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303304 "%s %14s %d\n", "pd", ":", fl->pd);
3305 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3306 "%s %9s %s\n", "spdname", ":", fl->spdname);
3307 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3308 "%s %6s %d\n", "file_close", ":", fl->file_close);
3309 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3310 "%s %8s %d\n", "sharedcb", ":", fl->sharedcb);
3311 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3312 "%s %9s %d\n", "profile", ":", fl->profile);
3313 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3314 "%s %3s %d\n", "smmu.coherent", ":",
3315 fl->sctx->smmu.coherent);
3316 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3317 "%s %4s %d\n", "smmu.enabled", ":",
3318 fl->sctx->smmu.enabled);
3319 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3320 "%s %9s %d\n", "smmu.cb", ":", fl->sctx->smmu.cb);
3321 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3322 "%s %5s %d\n", "smmu.secure", ":",
3323 fl->sctx->smmu.secure);
3324 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3325 "%s %5s %d\n", "smmu.faults", ":",
3326 fl->sctx->smmu.faults);
3327 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3328 "%s %s %d\n", "link.link_state",
3329 ":", *&me->channel[fl->cid].link.link_state);
3330
3331 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3332 "\n=======%s %s %s======\n", title,
3333 " LIST OF MAPS ", title);
3334
3335 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3336 "%-20s|%-20s|%-20s\n", "va", "phys", "size");
3337 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3338 "%s%s%s%s%s\n",
3339 single_line, single_line, single_line,
3340 single_line, single_line);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003341 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303342 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3343 "0x%-20lX|0x%-20llX|0x%-20zu\n\n",
3344 map->va, map->phys,
3345 map->size);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003346 }
3347 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303348 "%-20s|%-20s|%-20s|%-20s\n",
3349 "len", "refs",
3350 "raddr", "uncached");
3351 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3352 "%s%s%s%s%s\n",
3353 single_line, single_line, single_line,
3354 single_line, single_line);
3355 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
3356 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3357 "%-20zu|%-20d|0x%-20lX|%-20d\n\n",
3358 map->len, map->refs, map->raddr,
3359 map->uncached);
3360 }
3361 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3362 "%-20s|%-20s\n", "secure", "attr");
3363 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3364 "%s%s%s%s%s\n",
3365 single_line, single_line, single_line,
3366 single_line, single_line);
3367 hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
3368 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3369 "%-20d|0x%-20lX\n\n",
3370 map->secure, map->attr);
3371 }
3372 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303373 "%s %d\n\n",
3374 "KERNEL MEMORY ALLOCATION:", 1);
3375 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303376 "\n======%s %s %s======\n", title,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303377 " LIST OF CACHED BUFS ", title);
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303378 spin_lock(&fl->hlock);
3379 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303380 "%-19s|%-19s|%-19s|%-19s\n",
3381 "virt", "phys", "size", "dma_attr");
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303382 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3383 "%s%s%s%s%s\n", single_line, single_line,
3384 single_line, single_line, single_line);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303385 hlist_for_each_entry_safe(buf, n, &fl->cached_bufs, hn) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303386 len += scnprintf(fileinfo + len,
3387 DEBUGFS_SIZE - len,
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303388 "0x%-17p|0x%-17llX|%-19zu|0x%-17lX\n",
3389 buf->virt, (uint64_t)buf->phys, buf->size,
3390 buf->dma_attr);
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303391 }
3392 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3393 "\n%s %s %s\n", title,
3394 " LIST OF PENDING SMQCONTEXTS ", title);
3395
3396 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3397 "%-20s|%-10s|%-10s|%-10s|%-20s\n",
3398 "sc", "pid", "tgid", "used", "ctxid");
3399 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3400 "%s%s%s%s%s\n", single_line, single_line,
3401 single_line, single_line, single_line);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003402 hlist_for_each_entry_safe(ictx, n, &fl->clst.pending, hn) {
3403 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303404 "0x%-18X|%-10d|%-10d|%-10zu|0x%-20llX\n\n",
3405 ictx->sc, ictx->pid, ictx->tgid,
3406 ictx->used, ictx->ctxid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003407 }
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303408
Sathish Ambley1ca68232017-01-19 10:32:55 -08003409 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303410 "\n%s %s %s\n", title,
3411 " LIST OF INTERRUPTED SMQCONTEXTS ", title);
3412
3413 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3414 "%-20s|%-10s|%-10s|%-10s|%-20s\n",
3415 "sc", "pid", "tgid", "used", "ctxid");
3416 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3417 "%s%s%s%s%s\n", single_line, single_line,
3418 single_line, single_line, single_line);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003419 hlist_for_each_entry_safe(ictx, n, &fl->clst.interrupted, hn) {
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05303420 len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
3421 "%-20u|%-20d|%-20d|%-20zu|0x%-20llX\n\n",
3422 ictx->sc, ictx->pid, ictx->tgid,
3423 ictx->used, ictx->ctxid);
Sathish Ambley1ca68232017-01-19 10:32:55 -08003424 }
3425 spin_unlock(&fl->hlock);
3426 }
3427 if (len > DEBUGFS_SIZE)
3428 len = DEBUGFS_SIZE;
3429 ret = simple_read_from_buffer(buffer, count, position, fileinfo, len);
3430 kfree(fileinfo);
3431bail:
3432 return ret;
3433}
3434
3435static const struct file_operations debugfs_fops = {
3436 .open = fastrpc_debugfs_open,
3437 .read = fastrpc_debugfs_read,
3438};
Sathish Ambley36849af2017-02-02 09:35:55 -08003439static int fastrpc_channel_open(struct fastrpc_file *fl)
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003440{
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003441 struct fastrpc_apps *me = &gfa;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05303442 int cid = -1, ii, err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003443
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303444 mutex_lock(&me->smd_mutex);
3445
Sathish Ambley36849af2017-02-02 09:35:55 -08003446 VERIFY(err, fl && fl->sctx);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003447 if (err)
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303448 goto bail;
Sathish Ambley36849af2017-02-02 09:35:55 -08003449 cid = fl->cid;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05303450 VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
3451 if (err) {
3452 err = -ECHRNG;
c_mtharu314a4202017-11-15 22:09:17 +05303453 goto bail;
Mohammed Nayeem Ur Rahmancd836462020-04-01 14:30:33 +05303454 }
c_mtharue1a5ce12017-10-13 20:47:09 +05303455 if (me->channel[cid].ssrcount !=
3456 me->channel[cid].prevssrcount) {
3457 if (!me->channel[cid].issubsystemup) {
3458 VERIFY(err, 0);
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303459 if (err) {
3460 err = -ENOTCONN;
c_mtharue1a5ce12017-10-13 20:47:09 +05303461 goto bail;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303462 }
c_mtharue1a5ce12017-10-13 20:47:09 +05303463 }
3464 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003465 fl->ssrcount = me->channel[cid].ssrcount;
Tharun Kumar Merugu35173342018-02-08 16:13:17 +05303466 fl->refcount = 1;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003467 if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) ||
c_mtharue1a5ce12017-10-13 20:47:09 +05303468 (me->channel[cid].chan == NULL)) {
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303469 if (me->glink) {
3470 VERIFY(err, 0 == fastrpc_glink_register(cid, me));
3471 if (err)
3472 goto bail;
3473 VERIFY(err, 0 == fastrpc_glink_open(cid));
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05303474 VERIFY(err,
3475 wait_for_completion_timeout(&me->channel[cid].workport,
3476 RPC_TIMEOUT));
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303477 } else {
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05303478 if (me->channel[cid].chan == NULL) {
3479 VERIFY(err, !smd_named_open_on_edge(
3480 FASTRPC_SMD_GUID,
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303481 gcinfo[cid].channel,
3482 (smd_channel_t **)&me->channel[cid].chan,
3483 (void *)(uintptr_t)cid,
3484 smd_event_handler));
Tharun Kumar Merugu53a8ec92017-07-14 15:52:49 +05303485 VERIFY(err,
3486 wait_for_completion_timeout(&me->channel[cid].workport,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003487 RPC_TIMEOUT));
Mohammed Nayeem Ur Rahmana967be62019-09-23 20:56:15 +05303488
3489 }
3490 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003491 if (err) {
c_mtharue1a5ce12017-10-13 20:47:09 +05303492 me->channel[cid].chan = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003493 goto bail;
3494 }
3495 kref_init(&me->channel[cid].kref);
3496 pr_info("'opened /dev/%s c %d %d'\n", gcinfo[cid].name,
3497 MAJOR(me->dev_no), cid);
Tharun Kumar Meruguc42c6e22018-05-29 15:50:46 +05303498
3499 for (ii = 0; ii < FASTRPC_GLINK_INTENT_NUM && me->glink; ii++)
3500 glink_queue_rx_intent(me->channel[cid].chan, NULL,
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303501 FASTRPC_GLINK_INTENT_LEN);
Tharun Kumar Meruguc42c6e22018-05-29 15:50:46 +05303502
Tharun Kumar Merugud86fc8c2018-01-04 16:35:31 +05303503 if (cid == 0 && me->channel[cid].ssrcount !=
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003504 me->channel[cid].prevssrcount) {
c_mtharue1a5ce12017-10-13 20:47:09 +05303505 if (fastrpc_mmap_remove_ssr(fl))
3506 pr_err("ADSPRPC: SSR: Failed to unmap remote heap\n");
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003507 me->channel[cid].prevssrcount =
3508 me->channel[cid].ssrcount;
3509 }
3510 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003511
3512bail:
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303513 mutex_unlock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003514 return err;
3515}
3516
Sathish Ambley36849af2017-02-02 09:35:55 -08003517static int fastrpc_device_open(struct inode *inode, struct file *filp)
3518{
3519 int err = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05303520 struct fastrpc_file *fl = NULL;
Sathish Ambley36849af2017-02-02 09:35:55 -08003521 struct fastrpc_apps *me = &gfa;
3522
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
Sathish Ambley36849af2017-02-02 09:35:55 -08003540 context_list_ctor(&fl->clst);
3541 spin_lock_init(&fl->hlock);
3542 INIT_HLIST_HEAD(&fl->maps);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303543 INIT_HLIST_HEAD(&fl->perf);
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303544 INIT_HLIST_HEAD(&fl->cached_bufs);
3545 INIT_HLIST_HEAD(&fl->remote_bufs);
Sathish Ambley36849af2017-02-02 09:35:55 -08003546 INIT_HLIST_NODE(&fl->hn);
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05303547 fl->sessionid = 0;
Sathish Ambley36849af2017-02-02 09:35:55 -08003548 fl->apps = me;
3549 fl->mode = FASTRPC_MODE_SERIAL;
3550 fl->cid = -1;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303551 fl->dev_minor = dev_minor;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303552 fl->init_mem = NULL;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303553 fl->qos_request = 0;
Tharun Kumar Merugu35173342018-02-08 16:13:17 +05303554 fl->refcount = 0;
Sathish Ambley36849af2017-02-02 09:35:55 -08003555 filp->private_data = fl;
Tharun Kumar Meruguc31eac52018-01-02 11:42:45 +05303556 mutex_init(&fl->map_mutex);
Tharun Kumar Merugued7a8472018-01-25 12:10:15 +05303557 mutex_init(&fl->fl_map_mutex);
Sathish Ambley36849af2017-02-02 09:35:55 -08003558 spin_lock(&me->hlock);
3559 hlist_add_head(&fl->hn, &me->drivers);
3560 spin_unlock(&me->hlock);
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303561 mutex_init(&fl->perf_mutex);
Sathish Ambley36849af2017-02-02 09:35:55 -08003562 return 0;
3563}
3564
Edgar Flores1a772fa2020-02-07 14:59:29 -08003565static int fastrpc_set_process_info(struct fastrpc_file *fl)
3566{
3567 int err = 0, buf_size = 0;
3568 char strpid[PID_SIZE];
3569
3570 fl->tgid = current->tgid;
3571 snprintf(strpid, PID_SIZE, "%d", current->pid);
3572 buf_size = strlen(current->comm) + strlen("_") + strlen(strpid) + 1;
3573 fl->debug_buf = kzalloc(buf_size, GFP_KERNEL);
3574 if (!fl->debug_buf) {
3575 err = -ENOMEM;
3576 return err;
3577 }
3578 snprintf(fl->debug_buf, UL_SIZE, "%.10s%s%d",
3579 current->comm, "_", current->pid);
3580 fl->debugfs_file = debugfs_create_file(fl->debug_buf, 0644,
3581 debugfs_root, fl, &debugfs_fops);
3582 if (!fl->debugfs_file)
3583 pr_warn("Error: %s: %s: failed to create debugfs file %s\n",
3584 current->comm, __func__, fl->debug_buf);
3585 return err;
3586}
3587
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003588static int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info)
3589{
3590 int err = 0;
Sathish Ambley36849af2017-02-02 09:35:55 -08003591 uint32_t cid;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003592
c_mtharue1a5ce12017-10-13 20:47:09 +05303593 VERIFY(err, fl != NULL);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003594 if (err)
3595 goto bail;
Edgar Flores1a772fa2020-02-07 14:59:29 -08003596 err = fastrpc_set_process_info(fl);
3597 if (err)
3598 goto bail;
Sathish Ambley36849af2017-02-02 09:35:55 -08003599 if (fl->cid == -1) {
3600 cid = *info;
3601 VERIFY(err, cid < NUM_CHANNELS);
3602 if (err)
3603 goto bail;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303604 /* Check to see if the device node is non-secure */
zhaochenfc798572018-08-17 15:32:37 +08003605 if (fl->dev_minor == MINOR_NUM_DEV &&
3606 fl->apps->secure_flag == true) {
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05303607 /*
3608 * For non secure device node check and make sure that
3609 * the channel allows non-secure access
3610 * If not, bail. Session will not start.
3611 * cid will remain -1 and client will not be able to
3612 * invoke any other methods without failure
3613 */
3614 if (fl->apps->channel[cid].secure == SECURE_CHANNEL) {
3615 err = -EPERM;
3616 pr_err("adsprpc: GetInfo failed dev %d, cid %d, secure %d\n",
3617 fl->dev_minor, cid,
3618 fl->apps->channel[cid].secure);
3619 goto bail;
3620 }
3621 }
Sathish Ambley36849af2017-02-02 09:35:55 -08003622 fl->cid = cid;
3623 fl->ssrcount = fl->apps->channel[cid].ssrcount;
3624 VERIFY(err, !fastrpc_session_alloc_locked(
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303625 &fl->apps->channel[cid], 0, fl->sharedcb, &fl->sctx));
Sathish Ambley36849af2017-02-02 09:35:55 -08003626 if (err)
3627 goto bail;
3628 }
Tharun Kumar Merugu80be7d62017-08-02 11:03:22 +05303629 VERIFY(err, fl->sctx != NULL);
3630 if (err)
3631 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003632 *info = (fl->sctx->smmu.enabled ? 1 : 0);
3633bail:
3634 return err;
3635}
3636
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303637static int fastrpc_internal_control(struct fastrpc_file *fl,
3638 struct fastrpc_ioctl_control *cp)
3639{
Mohammed Nayeem Ur Rahman18d633f2019-05-28 15:11:40 +05303640 struct fastrpc_apps *me = &gfa;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303641 int err = 0;
3642 int latency;
3643
3644 VERIFY(err, !IS_ERR_OR_NULL(fl) && !IS_ERR_OR_NULL(fl->apps));
3645 if (err)
3646 goto bail;
3647 VERIFY(err, !IS_ERR_OR_NULL(cp));
3648 if (err)
3649 goto bail;
3650
3651 switch (cp->req) {
3652 case FASTRPC_CONTROL_LATENCY:
3653 latency = cp->lp.enable == FASTRPC_LATENCY_CTRL_ENB ?
3654 fl->apps->latency : PM_QOS_DEFAULT_VALUE;
3655 VERIFY(err, latency != 0);
3656 if (err)
3657 goto bail;
3658 if (!fl->qos_request) {
3659 pm_qos_add_request(&fl->pm_qos_req,
3660 PM_QOS_CPU_DMA_LATENCY, latency);
3661 fl->qos_request = 1;
3662 } else
3663 pm_qos_update_request(&fl->pm_qos_req, latency);
3664 break;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303665 case FASTRPC_CONTROL_SMMU:
Mohammed Nayeem Ur Rahman18d633f2019-05-28 15:11:40 +05303666 if (!me->legacy)
3667 fl->sharedcb = cp->smmu.sharedcb;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303668 break;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303669 case FASTRPC_CONTROL_KALLOC:
3670 cp->kalloc.kalloc_support = 1;
3671 break;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303672 default:
3673 err = -ENOTTY;
3674 break;
3675 }
3676bail:
3677 return err;
3678}
3679
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003680static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
3681 unsigned long ioctl_param)
3682{
3683 union {
Sathish Ambleybae51902017-07-03 15:00:49 -07003684 struct fastrpc_ioctl_invoke_crc inv;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003685 struct fastrpc_ioctl_mmap mmap;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303686 struct fastrpc_ioctl_mmap_64 mmap64;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003687 struct fastrpc_ioctl_munmap munmap;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303688 struct fastrpc_ioctl_munmap_64 munmap64;
c_mtharu7bd6a422017-10-17 18:15:37 +05303689 struct fastrpc_ioctl_munmap_fd munmap_fd;
Sathish Ambleyd6300c32017-01-18 09:50:43 -08003690 struct fastrpc_ioctl_init_attrs init;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003691 struct fastrpc_ioctl_perf perf;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303692 struct fastrpc_ioctl_control cp;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003693 } p;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303694 union {
3695 struct fastrpc_ioctl_mmap mmap;
3696 struct fastrpc_ioctl_munmap munmap;
3697 } i;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003698 void *param = (char *)ioctl_param;
3699 struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
3700 int size = 0, err = 0;
3701 uint32_t info;
3702
c_mtharue1a5ce12017-10-13 20:47:09 +05303703 p.inv.fds = NULL;
3704 p.inv.attrs = NULL;
Sathish Ambleybae51902017-07-03 15:00:49 -07003705 p.inv.crc = NULL;
tharun kumar9f899ea2017-07-03 17:07:03 +05303706 spin_lock(&fl->hlock);
3707 if (fl->file_close == 1) {
3708 err = EBADF;
3709 pr_warn("ADSPRPC: fastrpc_device_release is happening, So not sending any new requests to DSP");
3710 spin_unlock(&fl->hlock);
3711 goto bail;
3712 }
3713 spin_unlock(&fl->hlock);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003714
3715 switch (ioctl_num) {
3716 case FASTRPC_IOCTL_INVOKE:
3717 size = sizeof(struct fastrpc_ioctl_invoke);
Sathish Ambleybae51902017-07-03 15:00:49 -07003718 /* fall through */
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003719 case FASTRPC_IOCTL_INVOKE_FD:
3720 if (!size)
3721 size = sizeof(struct fastrpc_ioctl_invoke_fd);
3722 /* fall through */
3723 case FASTRPC_IOCTL_INVOKE_ATTRS:
3724 if (!size)
3725 size = sizeof(struct fastrpc_ioctl_invoke_attrs);
Sathish Ambleybae51902017-07-03 15:00:49 -07003726 /* fall through */
3727 case FASTRPC_IOCTL_INVOKE_CRC:
3728 if (!size)
3729 size = sizeof(struct fastrpc_ioctl_invoke_crc);
c_mtharue1a5ce12017-10-13 20:47:09 +05303730 K_COPY_FROM_USER(err, 0, &p.inv, param, size);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003731 if (err)
3732 goto bail;
3733 VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl, fl->mode,
3734 0, &p.inv)));
3735 if (err)
3736 goto bail;
3737 break;
3738 case FASTRPC_IOCTL_MMAP:
c_mtharue1a5ce12017-10-13 20:47:09 +05303739 K_COPY_FROM_USER(err, 0, &p.mmap, param,
3740 sizeof(p.mmap));
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +05303741 if (err)
3742 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003743 VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &p.mmap)));
3744 if (err)
3745 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +05303746 K_COPY_TO_USER(err, 0, param, &p.mmap, sizeof(p.mmap));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003747 if (err)
3748 goto bail;
3749 break;
3750 case FASTRPC_IOCTL_MUNMAP:
c_mtharue1a5ce12017-10-13 20:47:09 +05303751 K_COPY_FROM_USER(err, 0, &p.munmap, param,
3752 sizeof(p.munmap));
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +05303753 if (err)
3754 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003755 VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
3756 &p.munmap)));
3757 if (err)
3758 goto bail;
3759 break;
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303760 case FASTRPC_IOCTL_MMAP_64:
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303761 K_COPY_FROM_USER(err, 0, &p.mmap64, param,
3762 sizeof(p.mmap64));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303763 if (err)
3764 goto bail;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303765 get_fastrpc_ioctl_mmap_64(&p.mmap64, &i.mmap);
3766 VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, &i.mmap)));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303767 if (err)
3768 goto bail;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303769 put_fastrpc_ioctl_mmap_64(&p.mmap64, &i.mmap);
3770 K_COPY_TO_USER(err, 0, param, &p.mmap64, sizeof(p.mmap64));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303771 if (err)
3772 goto bail;
3773 break;
3774 case FASTRPC_IOCTL_MUNMAP_64:
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303775 K_COPY_FROM_USER(err, 0, &p.munmap64, param,
3776 sizeof(p.munmap64));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303777 if (err)
3778 goto bail;
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303779 get_fastrpc_ioctl_munmap_64(&p.munmap64, &i.munmap);
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303780 VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
Tharun Kumar Merugu92b5e132018-07-18 15:03:35 +05303781 &i.munmap)));
Tharun Kumar Merugu55be90d2018-05-31 11:41:03 +05303782 if (err)
3783 goto bail;
3784 break;
c_mtharu7bd6a422017-10-17 18:15:37 +05303785 case FASTRPC_IOCTL_MUNMAP_FD:
3786 K_COPY_FROM_USER(err, 0, &p.munmap_fd, param,
3787 sizeof(p.munmap_fd));
3788 if (err)
3789 goto bail;
3790 VERIFY(err, 0 == (err = fastrpc_internal_munmap_fd(fl,
3791 &p.munmap_fd)));
3792 if (err)
3793 goto bail;
3794 break;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003795 case FASTRPC_IOCTL_SETMODE:
3796 switch ((uint32_t)ioctl_param) {
3797 case FASTRPC_MODE_PARALLEL:
3798 case FASTRPC_MODE_SERIAL:
3799 fl->mode = (uint32_t)ioctl_param;
3800 break;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003801 case FASTRPC_MODE_PROFILE:
3802 fl->profile = (uint32_t)ioctl_param;
3803 break;
Tharun Kumar Merugud4d079482017-09-06 11:22:19 +05303804 case FASTRPC_MODE_SESSION:
3805 fl->sessionid = 1;
3806 fl->tgid |= (1 << SESSION_ID_INDEX);
3807 break;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003808 default:
3809 err = -ENOTTY;
3810 break;
3811 }
3812 break;
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003813 case FASTRPC_IOCTL_GETPERF:
c_mtharue1a5ce12017-10-13 20:47:09 +05303814 K_COPY_FROM_USER(err, 0, &p.perf,
3815 param, sizeof(p.perf));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003816 if (err)
3817 goto bail;
3818 p.perf.numkeys = sizeof(struct fastrpc_perf)/sizeof(int64_t);
3819 if (p.perf.keys) {
3820 char *keys = PERF_KEYS;
3821
c_mtharue1a5ce12017-10-13 20:47:09 +05303822 K_COPY_TO_USER(err, 0, (void *)p.perf.keys,
3823 keys, strlen(keys)+1);
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003824 if (err)
3825 goto bail;
3826 }
3827 if (p.perf.data) {
Tharun Kumar Merugu7c966dd2018-01-04 18:07:03 +05303828 struct fastrpc_perf *perf = NULL, *fperf = NULL;
3829 struct hlist_node *n = NULL;
3830
3831 mutex_lock(&fl->perf_mutex);
3832 hlist_for_each_entry_safe(perf, n, &fl->perf, hn) {
3833 if (perf->tid == current->pid) {
3834 fperf = perf;
3835 break;
3836 }
3837 }
3838
3839 mutex_unlock(&fl->perf_mutex);
3840
3841 if (fperf) {
3842 K_COPY_TO_USER(err, 0, (void *)p.perf.data,
3843 fperf, sizeof(*fperf));
3844 }
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003845 }
c_mtharue1a5ce12017-10-13 20:47:09 +05303846 K_COPY_TO_USER(err, 0, param, &p.perf, sizeof(p.perf));
Sathish Ambleya21b5b52017-01-11 16:11:01 -08003847 if (err)
3848 goto bail;
3849 break;
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303850 case FASTRPC_IOCTL_CONTROL:
c_mtharue1a5ce12017-10-13 20:47:09 +05303851 K_COPY_FROM_USER(err, 0, &p.cp, param,
3852 sizeof(p.cp));
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303853 if (err)
3854 goto bail;
3855 VERIFY(err, 0 == (err = fastrpc_internal_control(fl, &p.cp)));
3856 if (err)
3857 goto bail;
Tharun Kumar Merugue073de72018-07-30 23:57:47 +05303858 if (p.cp.req == FASTRPC_CONTROL_KALLOC) {
3859 K_COPY_TO_USER(err, 0, param, &p.cp, sizeof(p.cp));
3860 if (err)
3861 goto bail;
3862 }
Tharun Kumar Merugu5f6ca61c2017-08-11 11:43:11 +05303863 break;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003864 case FASTRPC_IOCTL_GETINFO:
c_mtharue1a5ce12017-10-13 20:47:09 +05303865 K_COPY_FROM_USER(err, 0, &info, param, sizeof(info));
Sathish Ambley36849af2017-02-02 09:35:55 -08003866 if (err)
3867 goto bail;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003868 VERIFY(err, 0 == (err = fastrpc_get_info(fl, &info)));
3869 if (err)
3870 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +05303871 K_COPY_TO_USER(err, 0, param, &info, sizeof(info));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003872 if (err)
3873 goto bail;
3874 break;
3875 case FASTRPC_IOCTL_INIT:
Sathish Ambleyd6300c32017-01-18 09:50:43 -08003876 p.init.attrs = 0;
3877 p.init.siglen = 0;
3878 size = sizeof(struct fastrpc_ioctl_init);
3879 /* fall through */
3880 case FASTRPC_IOCTL_INIT_ATTRS:
3881 if (!size)
3882 size = sizeof(struct fastrpc_ioctl_init_attrs);
c_mtharue1a5ce12017-10-13 20:47:09 +05303883 K_COPY_FROM_USER(err, 0, &p.init, param, size);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003884 if (err)
3885 goto bail;
Tharun Kumar Merugu4ea0eac2017-08-22 11:42:51 +05303886 VERIFY(err, p.init.init.filelen >= 0 &&
Tharun Kumar Merugud1f388a2017-10-01 10:51:11 +05303887 p.init.init.filelen < INIT_FILELEN_MAX);
3888 if (err)
3889 goto bail;
3890 VERIFY(err, p.init.init.memlen >= 0 &&
3891 p.init.init.memlen < INIT_MEMLEN_MAX);
Tharun Kumar Merugu4ea0eac2017-08-22 11:42:51 +05303892 if (err)
3893 goto bail;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303894 VERIFY(err, 0 == (err = fastrpc_init_process(fl, &p.init)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003895 if (err)
3896 goto bail;
3897 break;
3898
3899 default:
3900 err = -ENOTTY;
3901 pr_info("bad ioctl: %d\n", ioctl_num);
3902 break;
3903 }
3904 bail:
3905 return err;
3906}
3907
3908static int fastrpc_restart_notifier_cb(struct notifier_block *nb,
3909 unsigned long code,
3910 void *data)
3911{
3912 struct fastrpc_apps *me = &gfa;
3913 struct fastrpc_channel_ctx *ctx;
c_mtharue1a5ce12017-10-13 20:47:09 +05303914 struct notif_data *notifdata = data;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003915 int cid;
3916
3917 ctx = container_of(nb, struct fastrpc_channel_ctx, nb);
3918 cid = ctx - &me->channel[0];
3919 if (code == SUBSYS_BEFORE_SHUTDOWN) {
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303920 mutex_lock(&me->smd_mutex);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003921 ctx->ssrcount++;
c_mtharue1a5ce12017-10-13 20:47:09 +05303922 ctx->issubsystemup = 0;
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303923 if (ctx->chan) {
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05303924 if (me->glink)
3925 fastrpc_glink_close(ctx->chan, cid);
3926 else
3927 smd_close(ctx->chan);
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05303928 ctx->chan = NULL;
3929 pr_info("'restart notifier: closed /dev/%s c %d %d'\n",
3930 gcinfo[cid].name, MAJOR(me->dev_no), cid);
3931 }
3932 mutex_unlock(&me->smd_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05303933 if (cid == 0)
3934 me->staticpd_flags = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003935 fastrpc_notify_drivers(me, cid);
c_mtharue1a5ce12017-10-13 20:47:09 +05303936 } else if (code == SUBSYS_RAMDUMP_NOTIFICATION) {
3937 if (me->channel[0].remoteheap_ramdump_dev &&
3938 notifdata->enable_ramdump) {
3939 me->channel[0].ramdumpenabled = 1;
3940 }
3941 } else if (code == SUBSYS_AFTER_POWERUP) {
3942 ctx->issubsystemup = 1;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07003943 }
3944
3945 return NOTIFY_DONE;
3946}
3947
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303948static int fastrpc_pdr_notifier_cb(struct notifier_block *pdrnb,
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05303949 unsigned long code,
3950 void *data)
3951{
3952 struct fastrpc_apps *me = &gfa;
3953 struct fastrpc_static_pd *spd;
3954 struct notif_data *notifdata = data;
3955
3956 spd = container_of(pdrnb, struct fastrpc_static_pd, pdrnb);
3957 if (code == SERVREG_NOTIF_SERVICE_STATE_DOWN_V01) {
3958 mutex_lock(&me->smd_mutex);
3959 spd->pdrcount++;
3960 spd->ispdup = 0;
3961 pr_info("ADSPRPC: Audio PDR notifier %d %s\n",
3962 MAJOR(me->dev_no), spd->spdname);
3963 mutex_unlock(&me->smd_mutex);
3964 if (!strcmp(spd->spdname,
3965 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME))
3966 me->staticpd_flags = 0;
3967 fastrpc_notify_pdr_drivers(me, spd->spdname);
3968 } else if (code == SUBSYS_RAMDUMP_NOTIFICATION) {
3969 if (me->channel[0].remoteheap_ramdump_dev &&
3970 notifdata->enable_ramdump) {
3971 me->channel[0].ramdumpenabled = 1;
3972 }
3973 } else if (code == SERVREG_NOTIF_SERVICE_STATE_UP_V01) {
3974 spd->ispdup = 1;
3975 }
3976
3977 return NOTIFY_DONE;
3978}
3979
3980static int fastrpc_get_service_location_notify(struct notifier_block *nb,
3981 unsigned long opcode, void *data)
3982{
3983 struct fastrpc_static_pd *spd;
3984 struct pd_qmi_client_data *pdr = data;
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303985 int curr_state = 0, i = 0;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05303986
3987 spd = container_of(nb, struct fastrpc_static_pd, get_service_nb);
3988 if (opcode == LOCATOR_DOWN) {
3989 pr_err("ADSPRPC: Audio PD restart notifier locator down\n");
3990 return NOTIFY_DONE;
3991 }
3992
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05303993 for (i = 0; i < pdr->total_domains; i++) {
3994 if ((!strcmp(pdr->domain_list[i].name,
3995 "msm/adsp/audio_pd")) ||
3996 (!strcmp(pdr->domain_list[i].name,
3997 "msm/adsp/sensor_pd"))) {
3998 spd->pdrhandle =
3999 service_notif_register_notifier(
4000 pdr->domain_list[i].name,
4001 pdr->domain_list[i].instance_id,
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304002 &spd->pdrnb, &curr_state);
Tharun Kumar Meruguad4beb82018-05-10 19:51:48 +05304003 if (IS_ERR(spd->pdrhandle)) {
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304004 pr_err("ADSPRPC: Unable to register notifier\n");
Tharun Kumar Meruguad4beb82018-05-10 19:51:48 +05304005 } else if (curr_state ==
4006 SERVREG_NOTIF_SERVICE_STATE_UP_V01) {
4007 pr_info("ADSPRPC: STATE_UP_V01 received\n");
4008 spd->ispdup = 1;
4009 } else if (curr_state ==
4010 SERVREG_NOTIF_SERVICE_STATE_UNINIT_V01) {
4011 pr_info("ADSPRPC: STATE_UNINIT_V01 received\n");
4012 }
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304013 break;
4014 }
4015 }
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304016
4017 return NOTIFY_DONE;
4018}
4019
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004020static const struct file_operations fops = {
4021 .open = fastrpc_device_open,
4022 .release = fastrpc_device_release,
4023 .unlocked_ioctl = fastrpc_device_ioctl,
4024 .compat_ioctl = compat_fastrpc_device_ioctl,
4025};
4026
4027static const struct of_device_id fastrpc_match_table[] = {
4028 { .compatible = "qcom,msm-fastrpc-adsp", },
4029 { .compatible = "qcom,msm-fastrpc-compute", },
4030 { .compatible = "qcom,msm-fastrpc-compute-cb", },
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304031 { .compatible = "qcom,msm-fastrpc-legacy-compute", },
4032 { .compatible = "qcom,msm-fastrpc-legacy-compute-cb", },
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004033 { .compatible = "qcom,msm-adsprpc-mem-region", },
4034 {}
4035};
4036
4037static int fastrpc_cb_probe(struct device *dev)
4038{
4039 struct fastrpc_channel_ctx *chan;
4040 struct fastrpc_session_ctx *sess;
4041 struct of_phandle_args iommuspec;
4042 const char *name;
4043 unsigned int start = 0x80000000;
4044 int err = 0, i;
4045 int secure_vmid = VMID_CP_PIXEL;
4046
c_mtharue1a5ce12017-10-13 20:47:09 +05304047 VERIFY(err, NULL != (name = of_get_property(dev->of_node,
4048 "label", NULL)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004049 if (err)
4050 goto bail;
4051 for (i = 0; i < NUM_CHANNELS; i++) {
4052 if (!gcinfo[i].name)
4053 continue;
4054 if (!strcmp(name, gcinfo[i].name))
4055 break;
4056 }
4057 VERIFY(err, i < NUM_CHANNELS);
4058 if (err)
4059 goto bail;
4060 chan = &gcinfo[i];
4061 VERIFY(err, chan->sesscount < NUM_SESSIONS);
4062 if (err)
4063 goto bail;
4064
4065 VERIFY(err, !of_parse_phandle_with_args(dev->of_node, "iommus",
4066 "#iommu-cells", 0, &iommuspec));
4067 if (err)
4068 goto bail;
4069 sess = &chan->session[chan->sesscount];
4070 sess->smmu.cb = iommuspec.args[0] & 0xf;
4071 sess->used = 0;
4072 sess->smmu.coherent = of_property_read_bool(dev->of_node,
4073 "dma-coherent");
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304074 sess->smmu.sharedcb = of_property_read_bool(dev->of_node,
4075 "shared-cb");
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004076 sess->smmu.secure = of_property_read_bool(dev->of_node,
4077 "qcom,secure-context-bank");
4078 if (sess->smmu.secure)
4079 start = 0x60000000;
4080 VERIFY(err, !IS_ERR_OR_NULL(sess->smmu.mapping =
4081 arm_iommu_create_mapping(&platform_bus_type,
Tharun Kumar Meruguca183f92017-04-27 17:43:27 +05304082 start, 0x78000000)));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004083 if (err)
4084 goto bail;
4085
4086 if (sess->smmu.secure)
4087 iommu_domain_set_attr(sess->smmu.mapping->domain,
4088 DOMAIN_ATTR_SECURE_VMID,
4089 &secure_vmid);
4090
4091 VERIFY(err, !arm_iommu_attach_device(dev, sess->smmu.mapping));
4092 if (err)
4093 goto bail;
c_mtharue1a5ce12017-10-13 20:47:09 +05304094 sess->smmu.dev = dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004095 sess->smmu.enabled = 1;
4096 chan->sesscount++;
Sathish Ambley1ca68232017-01-19 10:32:55 -08004097 debugfs_global_file = debugfs_create_file("global", 0644, debugfs_root,
4098 NULL, &debugfs_fops);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004099bail:
4100 return err;
4101}
4102
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304103static int fastrpc_cb_legacy_probe(struct device *dev)
4104{
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304105 struct fastrpc_channel_ctx *chan;
4106 struct fastrpc_session_ctx *first_sess = NULL, *sess = NULL;
4107 const char *name;
4108 unsigned int *sids = NULL, sids_size = 0;
4109 int err = 0, ret = 0, i;
4110
4111 unsigned int start = 0x80000000;
4112
4113 VERIFY(err, NULL != (name = of_get_property(dev->of_node,
4114 "label", NULL)));
4115 if (err)
4116 goto bail;
4117
4118 for (i = 0; i < NUM_CHANNELS; i++) {
4119 if (!gcinfo[i].name)
4120 continue;
4121 if (!strcmp(name, gcinfo[i].name))
4122 break;
4123 }
4124 VERIFY(err, i < NUM_CHANNELS);
4125 if (err)
4126 goto bail;
4127
4128 chan = &gcinfo[i];
4129 VERIFY(err, chan->sesscount < NUM_SESSIONS);
4130 if (err)
4131 goto bail;
4132
4133 first_sess = &chan->session[chan->sesscount];
4134
4135 VERIFY(err, NULL != of_get_property(dev->of_node,
4136 "sids", &sids_size));
4137 if (err)
4138 goto bail;
4139
4140 VERIFY(err, NULL != (sids = kzalloc(sids_size, GFP_KERNEL)));
4141 if (err)
4142 goto bail;
4143 ret = of_property_read_u32_array(dev->of_node, "sids", sids,
4144 sids_size/sizeof(unsigned int));
4145 if (ret)
4146 goto bail;
4147
4148 VERIFY(err, !IS_ERR_OR_NULL(first_sess->smmu.mapping =
4149 arm_iommu_create_mapping(&platform_bus_type,
4150 start, 0x78000000)));
4151 if (err)
4152 goto bail;
4153
4154 VERIFY(err, !arm_iommu_attach_device(dev, first_sess->smmu.mapping));
4155 if (err)
4156 goto bail;
4157
4158
4159 for (i = 0; i < sids_size/sizeof(unsigned int); i++) {
4160 VERIFY(err, chan->sesscount < NUM_SESSIONS);
4161 if (err)
4162 goto bail;
4163 sess = &chan->session[chan->sesscount];
4164 sess->smmu.cb = sids[i];
4165 sess->smmu.dev = dev;
4166 sess->smmu.mapping = first_sess->smmu.mapping;
4167 sess->smmu.enabled = 1;
4168 sess->used = 0;
4169 sess->smmu.coherent = false;
4170 sess->smmu.secure = false;
4171 chan->sesscount++;
4172 }
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304173bail:
4174 kfree(sids);
4175 return err;
4176}
4177
4178
4179
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05304180static void init_secure_vmid_list(struct device *dev, char *prop_name,
4181 struct secure_vm *destvm)
4182{
4183 int err = 0;
4184 u32 len = 0, i = 0;
4185 u32 *rhvmlist = NULL;
4186 u32 *rhvmpermlist = NULL;
4187
4188 if (!of_find_property(dev->of_node, prop_name, &len))
4189 goto bail;
4190 if (len == 0)
4191 goto bail;
4192 len /= sizeof(u32);
4193 VERIFY(err, NULL != (rhvmlist = kcalloc(len, sizeof(u32), GFP_KERNEL)));
4194 if (err)
4195 goto bail;
4196 VERIFY(err, NULL != (rhvmpermlist = kcalloc(len, sizeof(u32),
4197 GFP_KERNEL)));
4198 if (err)
4199 goto bail;
4200 for (i = 0; i < len; i++) {
4201 err = of_property_read_u32_index(dev->of_node, prop_name, i,
4202 &rhvmlist[i]);
4203 rhvmpermlist[i] = PERM_READ | PERM_WRITE | PERM_EXEC;
4204 pr_info("ADSPRPC: Secure VMID = %d", rhvmlist[i]);
4205 if (err) {
4206 pr_err("ADSPRPC: Failed to read VMID\n");
4207 goto bail;
4208 }
4209 }
4210 destvm->vmid = rhvmlist;
4211 destvm->vmperm = rhvmpermlist;
4212 destvm->vmcount = len;
4213bail:
4214 if (err) {
4215 kfree(rhvmlist);
4216 kfree(rhvmpermlist);
4217 }
4218}
4219
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304220static void configure_secure_channels(uint32_t secure_domains)
4221{
4222 struct fastrpc_apps *me = &gfa;
4223 int ii = 0;
4224 /*
4225 * secure_domains contains the bitmask of the secure channels
4226 * Bit 0 - ADSP
4227 * Bit 1 - MDSP
4228 * Bit 2 - SLPI
4229 * Bit 3 - CDSP
4230 */
4231 for (ii = ADSP_DOMAIN_ID; ii <= CDSP_DOMAIN_ID; ++ii) {
4232 int secure = (secure_domains >> ii) & 0x01;
4233
4234 me->channel[ii].secure = secure;
4235 }
4236}
4237
4238
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004239static int fastrpc_probe(struct platform_device *pdev)
4240{
4241 int err = 0;
4242 struct fastrpc_apps *me = &gfa;
4243 struct device *dev = &pdev->dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004244 struct device_node *ion_node, *node;
4245 struct platform_device *ion_pdev;
4246 struct cma *cma;
4247 uint32_t val;
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304248 int ret = 0;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304249 uint32_t secure_domains;
c_mtharu63ffc012017-11-16 15:26:56 +05304250
4251 if (of_device_is_compatible(dev->of_node,
4252 "qcom,msm-fastrpc-compute")) {
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05304253 init_secure_vmid_list(dev, "qcom,adsp-remoteheap-vmid",
4254 &gcinfo[0].rhvm);
c_mtharu63ffc012017-11-16 15:26:56 +05304255
c_mtharu63ffc012017-11-16 15:26:56 +05304256
4257 of_property_read_u32(dev->of_node, "qcom,rpc-latency-us",
4258 &me->latency);
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304259 if (of_get_property(dev->of_node,
4260 "qcom,secure-domains", NULL) != NULL) {
4261 VERIFY(err, !of_property_read_u32(dev->of_node,
4262 "qcom,secure-domains",
4263 &secure_domains));
zhaochenfc798572018-08-17 15:32:37 +08004264 if (!err) {
4265 me->secure_flag = true;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304266 configure_secure_channels(secure_domains);
zhaochenfc798572018-08-17 15:32:37 +08004267 } else {
4268 me->secure_flag = false;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304269 pr_info("adsprpc: unable to read the domain configuration from dts\n");
zhaochenfc798572018-08-17 15:32:37 +08004270 }
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304271 }
c_mtharu63ffc012017-11-16 15:26:56 +05304272 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004273 if (of_device_is_compatible(dev->of_node,
4274 "qcom,msm-fastrpc-compute-cb"))
4275 return fastrpc_cb_probe(dev);
4276
4277 if (of_device_is_compatible(dev->of_node,
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304278 "qcom,msm-fastrpc-legacy-compute")) {
4279 me->glink = false;
Tharun Kumar Merugu4f2dcc82018-03-29 00:35:49 +05304280 me->legacy = 1;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304281 }
4282
4283 if (of_device_is_compatible(dev->of_node,
4284 "qcom,msm-fastrpc-legacy-compute-cb")){
4285 return fastrpc_cb_legacy_probe(dev);
4286 }
4287
4288 if (of_device_is_compatible(dev->of_node,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004289 "qcom,msm-adsprpc-mem-region")) {
4290 me->dev = dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004291 ion_node = of_find_compatible_node(NULL, NULL, "qcom,msm-ion");
4292 if (ion_node) {
4293 for_each_available_child_of_node(ion_node, node) {
4294 if (of_property_read_u32(node, "reg", &val))
4295 continue;
4296 if (val != ION_ADSP_HEAP_ID)
4297 continue;
4298 ion_pdev = of_find_device_by_node(node);
4299 if (!ion_pdev)
4300 break;
4301 cma = dev_get_cma_area(&ion_pdev->dev);
4302 if (cma) {
Tharun Kumar Merugu4f2dcc82018-03-29 00:35:49 +05304303 me->range.addr = cma_get_base(cma);
4304 me->range.size =
4305 (size_t)cma_get_size(cma);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004306 }
4307 break;
4308 }
4309 }
Tharun Kumar Merugu4f2dcc82018-03-29 00:35:49 +05304310 if (me->range.addr && !of_property_read_bool(dev->of_node,
Tharun Kumar Merugu6b7a4a22018-01-17 16:08:07 +05304311 "restrict-access")) {
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004312 int srcVM[1] = {VMID_HLOS};
4313 int destVM[4] = {VMID_HLOS, VMID_MSS_MSA, VMID_SSC_Q6,
4314 VMID_ADSP_Q6};
Sathish Ambley84d11862017-05-15 14:36:05 -07004315 int destVMperm[4] = {PERM_READ | PERM_WRITE | PERM_EXEC,
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004316 PERM_READ | PERM_WRITE | PERM_EXEC,
4317 PERM_READ | PERM_WRITE | PERM_EXEC,
4318 PERM_READ | PERM_WRITE | PERM_EXEC,
4319 };
4320
Tharun Kumar Merugu4f2dcc82018-03-29 00:35:49 +05304321 VERIFY(err, !hyp_assign_phys(me->range.addr,
4322 me->range.size, srcVM, 1,
4323 destVM, destVMperm, 4));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004324 if (err)
4325 goto bail;
4326 }
4327 return 0;
4328 }
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304329 if (of_property_read_bool(dev->of_node,
4330 "qcom,fastrpc-adsp-audio-pdr")) {
4331 int session;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004332
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304333 VERIFY(err, !fastrpc_get_adsp_session(
4334 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, &session));
4335 if (err)
4336 goto spdbail;
4337 me->channel[0].spd[session].get_service_nb.notifier_call =
4338 fastrpc_get_service_location_notify;
4339 ret = get_service_location(
4340 AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME,
4341 AUDIO_PDR_ADSP_SERVICE_NAME,
4342 &me->channel[0].spd[session].get_service_nb);
4343 if (ret)
4344 pr_err("ADSPRPC: Get service location failed: %d\n",
4345 ret);
4346 }
Tharun Kumar Merugu848c0952018-02-07 21:37:19 +05304347 if (of_property_read_bool(dev->of_node,
4348 "qcom,fastrpc-adsp-sensors-pdr")) {
4349 int session;
4350
4351 VERIFY(err, !fastrpc_get_adsp_session(
4352 SENSORS_PDR_SERVICE_LOCATION_CLIENT_NAME, &session));
4353 if (err)
4354 goto spdbail;
4355 me->channel[0].spd[session].get_service_nb.notifier_call =
4356 fastrpc_get_service_location_notify;
4357 ret = get_service_location(
4358 SENSORS_PDR_SERVICE_LOCATION_CLIENT_NAME,
4359 SENSORS_PDR_ADSP_SERVICE_NAME,
4360 &me->channel[0].spd[session].get_service_nb);
4361 if (ret)
4362 pr_err("ADSPRPC: Get service location failed: %d\n",
4363 ret);
4364 }
Tharun Kumar Merugudf860662018-01-17 19:59:50 +05304365spdbail:
4366 err = 0;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004367 VERIFY(err, !of_platform_populate(pdev->dev.of_node,
4368 fastrpc_match_table,
4369 NULL, &pdev->dev));
4370 if (err)
4371 goto bail;
4372bail:
4373 return err;
4374}
4375
4376static void fastrpc_deinit(void)
4377{
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05304378 struct fastrpc_apps *me = &gfa;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004379 struct fastrpc_channel_ctx *chan = gcinfo;
4380 int i, j;
4381
4382 for (i = 0; i < NUM_CHANNELS; i++, chan++) {
4383 if (chan->chan) {
4384 kref_put_mutex(&chan->kref,
Tharun Kumar Merugu642fcce2017-12-07 19:22:10 +05304385 fastrpc_channel_close, &me->smd_mutex);
c_mtharue1a5ce12017-10-13 20:47:09 +05304386 chan->chan = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004387 }
4388 for (j = 0; j < NUM_SESSIONS; j++) {
4389 struct fastrpc_session_ctx *sess = &chan->session[j];
c_mtharue1a5ce12017-10-13 20:47:09 +05304390 if (sess->smmu.dev) {
4391 arm_iommu_detach_device(sess->smmu.dev);
4392 sess->smmu.dev = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004393 }
4394 if (sess->smmu.mapping) {
4395 arm_iommu_release_mapping(sess->smmu.mapping);
c_mtharue1a5ce12017-10-13 20:47:09 +05304396 sess->smmu.mapping = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004397 }
4398 }
Tharun Kumar Merugu3937e912017-12-21 16:24:37 +05304399 kfree(chan->rhvm.vmid);
4400 kfree(chan->rhvm.vmperm);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004401 }
4402}
4403
4404static struct platform_driver fastrpc_driver = {
4405 .probe = fastrpc_probe,
4406 .driver = {
4407 .name = "fastrpc",
4408 .owner = THIS_MODULE,
4409 .of_match_table = fastrpc_match_table,
4410 },
4411};
4412
4413static int __init fastrpc_device_init(void)
4414{
4415 struct fastrpc_apps *me = &gfa;
c_mtharue1a5ce12017-10-13 20:47:09 +05304416 struct device *dev = NULL;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304417 struct device *secure_dev = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004418 int err = 0, i;
4419
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05304420 debugfs_root = debugfs_create_dir("adsprpc", NULL);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004421 memset(me, 0, sizeof(*me));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004422 fastrpc_init(me);
4423 me->dev = NULL;
Tharun Kumar Merugubbc78f22018-01-22 19:26:44 +05304424 me->glink = true;
zhaochenfc798572018-08-17 15:32:37 +08004425 me->secure_flag = false;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004426 VERIFY(err, 0 == platform_driver_register(&fastrpc_driver));
4427 if (err)
4428 goto register_bail;
4429 VERIFY(err, 0 == alloc_chrdev_region(&me->dev_no, 0, NUM_CHANNELS,
4430 DEVICE_NAME));
4431 if (err)
4432 goto alloc_chrdev_bail;
4433 cdev_init(&me->cdev, &fops);
4434 me->cdev.owner = THIS_MODULE;
4435 VERIFY(err, 0 == cdev_add(&me->cdev, MKDEV(MAJOR(me->dev_no), 0),
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304436 NUM_DEVICES));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004437 if (err)
4438 goto cdev_init_bail;
4439 me->class = class_create(THIS_MODULE, "fastrpc");
4440 VERIFY(err, !IS_ERR(me->class));
4441 if (err)
4442 goto class_create_bail;
4443 me->compat = (fops.compat_ioctl == NULL) ? 0 : 1;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304444
4445 /*
4446 * Create devices and register with sysfs
4447 * Create first device with minor number 0
4448 */
Sathish Ambley36849af2017-02-02 09:35:55 -08004449 dev = device_create(me->class, NULL,
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304450 MKDEV(MAJOR(me->dev_no), MINOR_NUM_DEV),
4451 NULL, DEVICE_NAME);
Sathish Ambley36849af2017-02-02 09:35:55 -08004452 VERIFY(err, !IS_ERR_OR_NULL(dev));
4453 if (err)
4454 goto device_create_bail;
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304455
4456 /* Create secure device with minor number for secure device */
4457 secure_dev = device_create(me->class, NULL,
4458 MKDEV(MAJOR(me->dev_no), MINOR_NUM_SECURE_DEV),
4459 NULL, DEVICE_NAME_SECURE);
4460 VERIFY(err, !IS_ERR_OR_NULL(secure_dev));
4461 if (err)
4462 goto device_create_bail;
4463
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004464 for (i = 0; i < NUM_CHANNELS; i++) {
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304465 me->channel[i].dev = secure_dev;
4466 if (i == CDSP_DOMAIN_ID)
4467 me->channel[i].dev = dev;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004468 me->channel[i].ssrcount = 0;
4469 me->channel[i].prevssrcount = 0;
c_mtharue1a5ce12017-10-13 20:47:09 +05304470 me->channel[i].issubsystemup = 1;
4471 me->channel[i].ramdumpenabled = 0;
4472 me->channel[i].remoteheap_ramdump_dev = NULL;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004473 me->channel[i].nb.notifier_call = fastrpc_restart_notifier_cb;
4474 me->channel[i].handle = subsys_notif_register_notifier(
4475 gcinfo[i].subsys,
4476 &me->channel[i].nb);
4477 }
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004478 me->client = msm_ion_client_create(DEVICE_NAME);
4479 VERIFY(err, !IS_ERR_OR_NULL(me->client));
4480 if (err)
4481 goto device_create_bail;
Mohammed Nayeem Ur Rahman492e3862018-08-17 12:53:43 +05304482
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004483 return 0;
4484device_create_bail:
4485 for (i = 0; i < NUM_CHANNELS; i++) {
Sathish Ambley36849af2017-02-02 09:35:55 -08004486 if (me->channel[i].handle)
4487 subsys_notif_unregister_notifier(me->channel[i].handle,
4488 &me->channel[i].nb);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004489 }
Sathish Ambley36849af2017-02-02 09:35:55 -08004490 if (!IS_ERR_OR_NULL(dev))
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304491 device_destroy(me->class, MKDEV(MAJOR(me->dev_no),
4492 MINOR_NUM_DEV));
4493 if (!IS_ERR_OR_NULL(secure_dev))
4494 device_destroy(me->class, MKDEV(MAJOR(me->dev_no),
4495 MINOR_NUM_SECURE_DEV));
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004496 class_destroy(me->class);
4497class_create_bail:
4498 cdev_del(&me->cdev);
4499cdev_init_bail:
4500 unregister_chrdev_region(me->dev_no, NUM_CHANNELS);
4501alloc_chrdev_bail:
4502register_bail:
4503 fastrpc_deinit();
4504 return err;
4505}
4506
4507static void __exit fastrpc_device_exit(void)
4508{
4509 struct fastrpc_apps *me = &gfa;
4510 int i;
4511
4512 fastrpc_file_list_dtor(me);
4513 fastrpc_deinit();
4514 for (i = 0; i < NUM_CHANNELS; i++) {
4515 if (!gcinfo[i].name)
4516 continue;
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004517 subsys_notif_unregister_notifier(me->channel[i].handle,
4518 &me->channel[i].nb);
4519 }
Tharun Kumar Merugud996b262018-07-18 22:28:53 +05304520
4521 /* Destroy the secure and non secure devices */
4522 device_destroy(me->class, MKDEV(MAJOR(me->dev_no), MINOR_NUM_DEV));
4523 device_destroy(me->class, MKDEV(MAJOR(me->dev_no),
4524 MINOR_NUM_SECURE_DEV));
4525
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004526 class_destroy(me->class);
4527 cdev_del(&me->cdev);
4528 unregister_chrdev_region(me->dev_no, NUM_CHANNELS);
4529 ion_client_destroy(me->client);
Sathish Ambley1ca68232017-01-19 10:32:55 -08004530 debugfs_remove_recursive(debugfs_root);
Sathish Ambley69e1ab02016-10-18 10:28:15 -07004531}
4532
4533late_initcall(fastrpc_device_init);
4534module_exit(fastrpc_device_exit);
4535
4536MODULE_LICENSE("GPL v2");