adsprpc_compat.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
  4. */
  5. #include <linux/compat.h>
  6. #include <linux/fs.h>
  7. #include <linux/uaccess.h>
  8. #include <linux/msm_ion.h>
  9. #include <linux/slab.h>
  10. #include "adsprpc_compat.h"
  11. #include "adsprpc_shared.h"
  12. #define COMPAT_FASTRPC_IOCTL_INVOKE \
  13. _IOWR('R', 1, struct compat_fastrpc_ioctl_invoke)
  14. #define COMPAT_FASTRPC_IOCTL_MMAP \
  15. _IOWR('R', 2, struct compat_fastrpc_ioctl_mmap)
  16. #define COMPAT_FASTRPC_IOCTL_MUNMAP \
  17. _IOWR('R', 3, struct compat_fastrpc_ioctl_munmap)
  18. #define COMPAT_FASTRPC_IOCTL_INVOKE_FD \
  19. _IOWR('R', 4, struct compat_fastrpc_ioctl_invoke_fd)
  20. #define COMPAT_FASTRPC_IOCTL_INIT \
  21. _IOWR('R', 6, struct compat_fastrpc_ioctl_init)
  22. #define COMPAT_FASTRPC_IOCTL_INVOKE_ATTRS \
  23. _IOWR('R', 7, struct compat_fastrpc_ioctl_invoke_attrs)
  24. #define COMPAT_FASTRPC_IOCTL_INIT_ATTRS \
  25. _IOWR('R', 10, struct compat_fastrpc_ioctl_init_attrs)
  26. #define COMPAT_FASTRPC_IOCTL_INVOKE_CRC \
  27. _IOWR('R', 11, struct compat_fastrpc_ioctl_invoke_crc)
  28. #define COMPAT_FASTRPC_IOCTL_CONTROL \
  29. _IOWR('R', 12, struct compat_fastrpc_ioctl_control)
  30. #define COMPAT_FASTRPC_IOCTL_MMAP_64 \
  31. _IOWR('R', 14, struct compat_fastrpc_ioctl_mmap_64)
  32. #define COMPAT_FASTRPC_IOCTL_MUNMAP_64 \
  33. _IOWR('R', 15, struct compat_fastrpc_ioctl_munmap_64)
  34. #define COMPAT_FASTRPC_IOCTL_GET_DSP_INFO \
  35. _IOWR('R', 17, \
  36. struct compat_fastrpc_ioctl_capability)
  37. #define COMPAT_FASTRPC_IOCTL_INVOKE2 \
  38. _IOWR('R', 18, struct compat_fastrpc_ioctl_invoke2)
  39. #define COMPAT_FASTRPC_IOCTL_MEM_MAP \
  40. _IOWR('R', 19, struct compat_fastrpc_ioctl_mem_map)
  41. #define COMPAT_FASTRPC_IOCTL_MEM_UNMAP \
  42. _IOWR('R', 20, struct compat_fastrpc_ioctl_mem_unmap)
  43. #define COMPAT_FASTRPC_IOCTL_INVOKE_PERF \
  44. _IOWR('R', 21, struct compat_fastrpc_ioctl_invoke_perf)
  45. #define COMPAT_FASTRPC_IOCTL_DSPSIGNAL_CREATE \
  46. _IOWR('R', 23, struct fastrpc_ioctl_dspsignal_create)
  47. #define COMPAT_FASTRPC_IOCTL_DSPSIGNAL_DESTROY \
  48. _IOWR('R', 24, struct fastrpc_ioctl_dspsignal_destroy)
  49. #define COMPAT_FASTRPC_IOCTL_DSPSIGNAL_SIGNAL \
  50. _IOWR('R', 25, struct fastrpc_ioctl_dspsignal_signal)
  51. #define COMPAT_FASTRPC_IOCTL_DSPSIGNAL_WAIT \
  52. _IOWR('R', 26, struct fastrpc_ioctl_dspsignal_wait)
  53. #define COMPAT_FASTRPC_IOCTL_DSPSIGNAL_CANCEL_WAIT \
  54. _IOWR('R', 27, struct fastrpc_ioctl_dspsignal_cancel_wait)
  55. struct compat_remote_buf {
  56. compat_uptr_t pv; /* buffer pointer */
  57. compat_size_t len; /* length of buffer */
  58. };
  59. union compat_remote_arg {
  60. struct compat_remote_buf buf;
  61. compat_uint_t h;
  62. };
  63. struct compat_fastrpc_ioctl_invoke {
  64. compat_uint_t handle; /* remote handle */
  65. compat_uint_t sc; /* scalars describing the data */
  66. compat_uptr_t pra; /* remote arguments list */
  67. };
  68. struct compat_fastrpc_ioctl_invoke_fd {
  69. struct compat_fastrpc_ioctl_invoke inv;
  70. compat_uptr_t fds; /* fd list */
  71. };
  72. struct compat_fastrpc_ioctl_invoke_attrs {
  73. struct compat_fastrpc_ioctl_invoke inv;
  74. compat_uptr_t fds; /* fd list */
  75. compat_uptr_t attrs; /* attribute list */
  76. };
  77. struct compat_fastrpc_ioctl_invoke_crc {
  78. struct compat_fastrpc_ioctl_invoke inv;
  79. compat_uptr_t fds; /* fd list */
  80. compat_uptr_t attrs; /* attribute list */
  81. compat_uptr_t crc; /* crc list */
  82. };
  83. struct compat_fastrpc_ioctl_invoke_perf {
  84. struct compat_fastrpc_ioctl_invoke inv;
  85. compat_uptr_t fds;
  86. compat_uptr_t attrs;
  87. compat_uptr_t crc;
  88. compat_uptr_t perf_kernel;
  89. compat_uptr_t perf_dsp;
  90. };
  91. struct compat_fastrpc_ioctl_invoke_async {
  92. struct compat_fastrpc_ioctl_invoke inv;
  93. compat_uptr_t fds; /* fd list */
  94. compat_uptr_t attrs; /* attribute list */
  95. compat_uptr_t crc; /* crc list */
  96. compat_uptr_t perf_kernel; /* Kernel perf data pointer */
  97. compat_uptr_t perf_dsp; /* DSP perf data pointer */
  98. compat_uptr_t job; /* Async job */
  99. };
  100. struct compat_fastrpc_ioctl_invoke_async_no_perf {
  101. struct compat_fastrpc_ioctl_invoke inv;
  102. compat_uptr_t fds; /* fd list */
  103. compat_uptr_t attrs; /* attribute list */
  104. compat_uptr_t crc; /* crc list */
  105. compat_uptr_t job; /* Async job */
  106. };
  107. struct compat_fastrpc_ioctl_invoke2 {
  108. compat_uint_t req; /* type of invocation request */
  109. compat_uptr_t invparam; /* invocation request param */
  110. compat_uint_t size; /* size of invocation param */
  111. compat_int_t err; /* reserved */
  112. };
  113. struct compat_fastrpc_ioctl_async_response {
  114. compat_u64 jobid; /* job id generated by user */
  115. compat_int_t result; /* result from DSP */
  116. compat_uptr_t perf_kernel; /* Kernel perf data pointer */
  117. compat_uptr_t perf_dsp; /* DSP perf data pointer */
  118. compat_uint_t handle;
  119. compat_uint_t sc;
  120. };
  121. struct compat_fastrpc_ioctl_notif_rsp {
  122. compat_int_t domain; /* Domain of User PD */
  123. compat_int_t session; /* Session ID of User PD */
  124. compat_uint_t status; /* Status of the process */
  125. };
  126. struct compat_fastrpc_mem_map {
  127. compat_int_t fd; /* ion fd */
  128. compat_int_t offset; /* buffer offset */
  129. compat_uint_t flags; /* flags to control memory map */
  130. compat_uint_t attrs; /* buffer attributes used for SMMU mapping */
  131. compat_uptr_t vaddrin; /* virtual address */
  132. compat_size_t length; /* buffer length */
  133. compat_u64 vaddrout; /* dsp virtual address */
  134. };
  135. struct compat_fastrpc_ioctl_mem_map {
  136. compat_int_t version;
  137. union {
  138. struct compat_fastrpc_mem_map m;
  139. compat_int_t reserved[MAP_RESERVED_NUM];
  140. };
  141. };
  142. struct compat_fastrpc_mem_unmap {
  143. compat_int_t fd; /* ion fd */
  144. compat_u64 vaddr; /* dsp virtual address */
  145. compat_size_t length; /* buffer length */
  146. };
  147. struct compat_fastrpc_ioctl_mem_unmap {
  148. compat_int_t version;
  149. union {
  150. struct compat_fastrpc_mem_unmap um;
  151. compat_int_t reserved[UNMAP_RESERVED_NUM];
  152. };
  153. };
  154. struct compat_fastrpc_ioctl_mmap {
  155. compat_int_t fd; /* ion fd */
  156. compat_uint_t flags; /* flags for dsp to map with */
  157. compat_uptr_t vaddrin; /* optional virtual address */
  158. compat_size_t size; /* size */
  159. compat_uptr_t vaddrout; /* dsps virtual address */
  160. };
  161. struct compat_fastrpc_ioctl_mmap_64 {
  162. compat_int_t fd; /* ion fd */
  163. compat_uint_t flags; /* flags for dsp to map with */
  164. compat_u64 vaddrin; /* optional virtual address */
  165. compat_size_t size; /* size */
  166. compat_u64 vaddrout; /* dsps virtual address */
  167. };
  168. struct compat_fastrpc_ioctl_munmap {
  169. compat_uptr_t vaddrout; /* address to unmap */
  170. compat_size_t size; /* size */
  171. };
  172. struct compat_fastrpc_ioctl_munmap_64 {
  173. compat_u64 vaddrout; /* address to unmap */
  174. compat_size_t size; /* size */
  175. };
  176. struct compat_fastrpc_ioctl_init {
  177. compat_uint_t flags; /* one of FASTRPC_INIT_* macros */
  178. compat_uptr_t file; /* pointer to elf file */
  179. compat_int_t filelen; /* elf file length */
  180. compat_int_t filefd; /* ION fd for the file */
  181. compat_uptr_t mem; /* mem for the PD */
  182. compat_int_t memlen; /* mem length */
  183. compat_int_t memfd; /* ION fd for the mem */
  184. };
  185. struct compat_fastrpc_ioctl_init_attrs {
  186. struct compat_fastrpc_ioctl_init init;
  187. compat_int_t attrs; /* attributes to init process */
  188. compat_int_t siglen; /* test signature file length */
  189. };
  190. #define FASTRPC_CONTROL_LATENCY (1)
  191. struct compat_fastrpc_ctrl_latency {
  192. compat_uint_t enable; /* latency control enable */
  193. compat_uint_t latency; /* target latency in us */
  194. };
  195. #define FASTRPC_CONTROL_KALLOC (3)
  196. struct compat_fastrpc_ctrl_kalloc {
  197. compat_uint_t kalloc_support; /* Remote memory allocation from kernel */
  198. };
  199. struct compat_fastrpc_ctrl_wakelock {
  200. compat_uint_t enable; /* wakelock control enable */
  201. };
  202. struct compat_fastrpc_ctrl_pm {
  203. compat_uint_t timeout; /* timeout(in ms) for PM to keep system awake */
  204. };
  205. struct compat_fastrpc_ioctl_control {
  206. compat_uint_t req;
  207. union {
  208. struct compat_fastrpc_ctrl_latency lp;
  209. struct compat_fastrpc_ctrl_kalloc kalloc;
  210. struct compat_fastrpc_ctrl_wakelock wp;
  211. struct compat_fastrpc_ctrl_pm pm;
  212. };
  213. };
  214. struct compat_fastrpc_ioctl_capability {
  215. /*
  216. * @param[in]: DSP domain ADSP_DOMAIN_ID,
  217. * SDSP_DOMAIN_ID, or CDSP_DOMAIN_ID
  218. */
  219. compat_uint_t domain;
  220. /*
  221. * @param[in]: One of the DSP attributes
  222. * from enum remote_dsp_attributes
  223. */
  224. compat_uint_t attribute_ID;
  225. /*
  226. * @param[out]: Result of the DSP
  227. * capability query based on attribute_ID
  228. */
  229. compat_uint_t capability;
  230. };
  231. static int compat_get_fastrpc_ioctl_invoke(
  232. struct compat_fastrpc_ioctl_invoke_async __user *inv32,
  233. struct fastrpc_ioctl_invoke_async *inv,
  234. unsigned int cmd, unsigned int sc)
  235. {
  236. compat_uint_t u = 0;
  237. compat_size_t s;
  238. compat_uptr_t p, k;
  239. union compat_remote_arg *pra32;
  240. union remote_arg *pra;
  241. int err = 0, len = 0, j = 0;
  242. len = REMOTE_SCALARS_LENGTH(sc);
  243. pra = (union remote_arg *)(inv + 1);
  244. memcpy(&inv->inv.pra, &pra, sizeof(pra));
  245. memcpy(&inv->inv.sc, &sc, sizeof(sc));
  246. err |= get_user(u, &inv32->inv.handle);
  247. memcpy(&inv->inv.handle, &u, sizeof(u));
  248. err |= get_user(p, &inv32->inv.pra);
  249. if (err)
  250. return err;
  251. pra32 = compat_ptr(p);
  252. pra = (union remote_arg *)(inv + 1);
  253. for (j = 0; j < len; j++) {
  254. err |= get_user(p, &pra32[j].buf.pv);
  255. memcpy((uintptr_t *)&pra[j].buf.pv, &p, sizeof(p));
  256. err |= get_user(s, &pra32[j].buf.len);
  257. memcpy(&pra[j].buf.len, &s, sizeof(s));
  258. }
  259. inv->fds = NULL;
  260. if (cmd != COMPAT_FASTRPC_IOCTL_INVOKE) {
  261. err |= get_user(p, &inv32->fds);
  262. memcpy(&inv->fds, &p, sizeof(p));
  263. }
  264. inv->attrs = NULL;
  265. if ((cmd == COMPAT_FASTRPC_IOCTL_INVOKE_ATTRS) ||
  266. (cmd == COMPAT_FASTRPC_IOCTL_INVOKE_CRC) ||
  267. (cmd == COMPAT_FASTRPC_IOCTL_INVOKE_PERF) ||
  268. (cmd == FASTRPC_INVOKE2_ASYNC)) {
  269. err |= get_user(p, &inv32->attrs);
  270. memcpy(&inv->attrs, &p, sizeof(p));
  271. }
  272. inv->crc = NULL;
  273. if ((cmd == COMPAT_FASTRPC_IOCTL_INVOKE_CRC) ||
  274. (cmd == COMPAT_FASTRPC_IOCTL_INVOKE_PERF)) {
  275. err |= get_user(p, &inv32->crc);
  276. memcpy(&inv->crc, &p, sizeof(p));
  277. }
  278. inv->job = NULL;
  279. if (cmd == FASTRPC_INVOKE2_ASYNC) {
  280. err |= get_user(p, &inv32->job);
  281. memcpy(&inv->job, &p, sizeof(p));
  282. }
  283. inv->perf_kernel = NULL;
  284. inv->perf_dsp = NULL;
  285. if ((cmd == COMPAT_FASTRPC_IOCTL_INVOKE_PERF) || (cmd == FASTRPC_INVOKE2_ASYNC)) {
  286. err |= get_user(k, &inv32->perf_kernel);
  287. err |= get_user(p, &inv32->perf_dsp);
  288. memcpy(&inv->perf_kernel, &k, sizeof(k));
  289. memcpy(&inv->perf_dsp, &p, sizeof(p));
  290. }
  291. return err;
  292. }
  293. static int compat_fastrpc_ioctl_invoke(struct file *filp,
  294. unsigned int cmd, unsigned long arg)
  295. {
  296. struct compat_fastrpc_ioctl_invoke_async __user *inv32;
  297. struct fastrpc_ioctl_invoke_async *inv = NULL;
  298. compat_uint_t sc = 0;
  299. int err = 0, len = 0;
  300. struct fastrpc_file *fl = (struct fastrpc_file *)filp->private_data;
  301. inv32 = compat_ptr(arg);
  302. err = get_user(sc, &inv32->inv.sc);
  303. if (err)
  304. return err;
  305. len = REMOTE_SCALARS_LENGTH(sc);
  306. VERIFY(err, NULL != (inv = kmalloc(
  307. sizeof(*inv) + len * sizeof(union remote_arg), GFP_KERNEL)));
  308. if (err)
  309. return -EFAULT;
  310. VERIFY(err, 0 == compat_get_fastrpc_ioctl_invoke(inv32,
  311. inv, cmd, sc));
  312. if (err) {
  313. kfree(inv);
  314. return err;
  315. }
  316. VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
  317. fl->mode, COMPAT_MSG, inv)));
  318. kfree(inv);
  319. return err;
  320. }
  321. static int compat_get_fastrpc_ioctl_invoke2(
  322. struct compat_fastrpc_ioctl_invoke2 __user *inv32,
  323. struct fastrpc_ioctl_invoke2 **inva,
  324. unsigned int cmd)
  325. {
  326. int err = 0;
  327. compat_uptr_t pparam, p;
  328. compat_uint_t req, size, ref_size = 0;
  329. struct fastrpc_ioctl_invoke2 *inv2_user = NULL;
  330. struct fastrpc_ioctl_invoke_async *asyncinv_user;
  331. err = get_user(req, &inv32->req);
  332. err |= get_user(pparam, &inv32->invparam);
  333. err |= get_user(size, &inv32->size);
  334. if (err)
  335. goto bail;
  336. switch (req) {
  337. case FASTRPC_INVOKE2_ASYNC:
  338. {
  339. struct compat_fastrpc_ioctl_invoke_async __user *lasync32;
  340. struct compat_fastrpc_ioctl_invoke_async_no_perf __user *lasync32_old;
  341. compat_uint_t sc = 0;
  342. int len = 0;
  343. VERIFY(err, size <= sizeof(*lasync32));
  344. if (err) {
  345. err = -EBADE;
  346. goto bail;
  347. }
  348. lasync32 = compat_ptr(pparam);
  349. err = get_user(sc, &lasync32->inv.sc);
  350. if (err)
  351. goto bail;
  352. len = REMOTE_SCALARS_LENGTH(sc);
  353. VERIFY(err, NULL != (inv2_user = kmalloc(
  354. sizeof(*inv2_user) + sizeof(*asyncinv_user) +
  355. len * sizeof(union remote_arg), GFP_KERNEL)));
  356. if (err) {
  357. err = -EFAULT;
  358. goto bail;
  359. }
  360. asyncinv_user =
  361. (struct fastrpc_ioctl_invoke_async *)(inv2_user + 1);
  362. if (size < sizeof(struct compat_fastrpc_ioctl_invoke_async)) {
  363. lasync32_old = compat_ptr(pparam);
  364. VERIFY(err, 0 == compat_get_fastrpc_ioctl_invoke(lasync32,
  365. asyncinv_user, COMPAT_FASTRPC_IOCTL_INVOKE_CRC, sc));
  366. if (err)
  367. goto bail;
  368. asyncinv_user->job = NULL;
  369. err |= get_user(p, &lasync32_old->job);
  370. memcpy(&asyncinv_user->job, &p, sizeof(p));
  371. asyncinv_user->perf_kernel = NULL;
  372. asyncinv_user->perf_dsp = NULL;
  373. } else {
  374. VERIFY(err, 0 == compat_get_fastrpc_ioctl_invoke(lasync32,
  375. asyncinv_user, req, sc));
  376. }
  377. if (err)
  378. goto bail;
  379. memcpy(&inv2_user->req, &req, sizeof(req));
  380. inv2_user->invparam = (uintptr_t)asyncinv_user;
  381. inv2_user->size = sizeof(*asyncinv_user);
  382. if (err)
  383. goto bail;
  384. break;
  385. }
  386. case FASTRPC_INVOKE2_ASYNC_RESPONSE:
  387. ref_size = sizeof(struct compat_fastrpc_ioctl_async_response);
  388. VERIFY(err, size <= ref_size);
  389. if (err) {
  390. err = -EBADE;
  391. goto bail;
  392. }
  393. fallthrough;
  394. case FASTRPC_INVOKE2_KERNEL_OPTIMIZATIONS:
  395. if (!ref_size) {
  396. ref_size = sizeof(uint32_t);
  397. VERIFY(err, size == ref_size);
  398. if (err) {
  399. err = -EBADE;
  400. goto bail;
  401. }
  402. }
  403. fallthrough;
  404. case FASTRPC_INVOKE2_STATUS_NOTIF:
  405. {
  406. if (!ref_size) {
  407. ref_size = sizeof(struct compat_fastrpc_ioctl_notif_rsp);
  408. VERIFY(err, size == ref_size);
  409. if (err) {
  410. err = -EBADE;
  411. goto bail;
  412. }
  413. }
  414. VERIFY(err, NULL != (inv2_user = kmalloc(
  415. sizeof(*inv2_user), GFP_KERNEL)));
  416. if (err) {
  417. err = -EFAULT;
  418. goto bail;
  419. }
  420. memcpy(&inv2_user->req, &req, sizeof(req));
  421. memcpy(&inv2_user->invparam, &pparam, sizeof(pparam));
  422. memcpy(&inv2_user->size, &size, sizeof(size));
  423. if (err)
  424. goto bail;
  425. break;
  426. }
  427. default:
  428. err = -ENOTTY;
  429. break;
  430. }
  431. *inva = inv2_user;
  432. bail:
  433. return err;
  434. }
  435. static int compat_fastrpc_ioctl_invoke2(struct file *filp,
  436. unsigned int cmd, unsigned long arg)
  437. {
  438. struct compat_fastrpc_ioctl_invoke2 __user *inv32;
  439. struct fastrpc_ioctl_invoke2 *inv = NULL;
  440. int err = 0;
  441. struct fastrpc_file *fl = (struct fastrpc_file *)filp->private_data;
  442. inv32 = compat_ptr(arg);
  443. VERIFY(err, 0 == compat_get_fastrpc_ioctl_invoke2(inv32,
  444. &inv, cmd));
  445. if (err) {
  446. kfree(inv);
  447. return err;
  448. }
  449. VERIFY(err, 0 == (err = fastrpc_internal_invoke2(fl, inv, true)));
  450. kfree(inv);
  451. return err;
  452. }
  453. static int compat_get_fastrpc_ioctl_mem_map(
  454. struct compat_fastrpc_ioctl_mem_map __user *map32,
  455. struct fastrpc_ioctl_mem_map *map)
  456. {
  457. compat_uint_t u = 0;
  458. compat_int_t i = 0;
  459. compat_size_t s = 0;
  460. compat_uptr_t p = 0;
  461. int err;
  462. err = get_user(i, &map32->version);
  463. if (err || i != 0)
  464. return -EINVAL;
  465. memcpy(&map->version, &i, sizeof(i));
  466. err |= get_user(i, &map32->m.fd);
  467. memcpy(&map->m.fd, &i, sizeof(i));
  468. err |= get_user(i, &map32->m.offset);
  469. memcpy(&map->m.offset, &i, sizeof(i));
  470. err |= get_user(u, &map32->m.flags);
  471. memcpy(&map->m.flags, &u, sizeof(u));
  472. err |= get_user(p, &map32->m.vaddrin);
  473. memcpy(&map->m.vaddrin, &s, sizeof(s));
  474. err |= get_user(s, &map32->m.length);
  475. memcpy(&map->m.length, &s, sizeof(s));
  476. err |= get_user(u, &map32->m.attrs);
  477. memcpy(&map->m.attrs, &u, sizeof(u));
  478. return err;
  479. }
  480. static int compat_put_fastrpc_ioctl_mem_map(
  481. struct compat_fastrpc_ioctl_mem_map __user *map32,
  482. struct fastrpc_ioctl_mem_map *map)
  483. {
  484. compat_u64 p;
  485. int err = 0;
  486. memcpy(&p, &map->m.vaddrout, sizeof(map->m.vaddrout));
  487. err |= put_user(p, &map32->m.vaddrout);
  488. return err;
  489. }
  490. static int compat_get_fastrpc_ioctl_mem_unmap(
  491. struct compat_fastrpc_ioctl_mem_unmap __user *unmap32,
  492. struct fastrpc_ioctl_mem_unmap __user *unmap)
  493. {
  494. compat_int_t i;
  495. compat_size_t s;
  496. compat_u64 p;
  497. int err;
  498. err = get_user(i, &unmap32->version);
  499. if (err || i != 0)
  500. return -EINVAL;
  501. memcpy(&unmap->version, &i, sizeof(i));
  502. err |= get_user(i, &unmap32->um.fd);
  503. memcpy(&unmap->um.fd, &i, sizeof(i));
  504. err |= get_user(p, &unmap32->um.vaddr);
  505. memcpy(&unmap->um.vaddr, &p, sizeof(p));
  506. err |= get_user(s, &unmap32->um.length);
  507. memcpy(&unmap->um.length, &s, sizeof(s));
  508. return err;
  509. }
  510. static int compat_get_fastrpc_ioctl_mmap(
  511. struct compat_fastrpc_ioctl_mmap __user *map32,
  512. struct fastrpc_ioctl_mmap __user *map)
  513. {
  514. compat_uint_t u;
  515. compat_int_t i;
  516. compat_size_t s;
  517. compat_uptr_t p;
  518. int err;
  519. err = get_user(i, &map32->fd);
  520. memcpy(&map->fd, &i, sizeof(i));
  521. err |= get_user(u, &map32->flags);
  522. memcpy(&map->flags, &u, sizeof(u));
  523. err |= get_user(p, &map32->vaddrin);
  524. memcpy((uintptr_t *)&map->vaddrin, &p, sizeof(p));
  525. err |= get_user(s, &map32->size);
  526. memcpy(&map->size, &s, sizeof(s));
  527. return err;
  528. }
  529. static int compat_get_fastrpc_ioctl_mmap_64(
  530. struct compat_fastrpc_ioctl_mmap_64 __user *map32,
  531. struct fastrpc_ioctl_mmap __user *map)
  532. {
  533. compat_uint_t u;
  534. compat_int_t i;
  535. compat_size_t s;
  536. compat_u64 p;
  537. int err;
  538. err = get_user(i, &map32->fd);
  539. memcpy(&map->fd, &i, sizeof(i));
  540. err |= get_user(u, &map32->flags);
  541. memcpy(&map->flags, &u, sizeof(u));
  542. err |= get_user(p, &map32->vaddrin);
  543. memcpy(&map->vaddrin, &p, sizeof(p));
  544. err |= get_user(s, &map32->size);
  545. memcpy(&map->size, &s, sizeof(s));
  546. return err;
  547. }
  548. static int compat_put_fastrpc_ioctl_mmap(
  549. struct compat_fastrpc_ioctl_mmap __user *map32,
  550. struct fastrpc_ioctl_mmap __user *map)
  551. {
  552. compat_uptr_t p;
  553. int err = 0;
  554. memcpy(&p, &map->vaddrout, sizeof(p));
  555. err |= put_user(p, &map32->vaddrout);
  556. return err;
  557. }
  558. static int compat_put_fastrpc_ioctl_mmap_64(
  559. struct compat_fastrpc_ioctl_mmap_64 __user *map32,
  560. struct fastrpc_ioctl_mmap __user *map)
  561. {
  562. compat_u64 p;
  563. int err = 0;
  564. memcpy(&p, &map->vaddrout, sizeof(map->vaddrout));
  565. err |= put_user(p, &map32->vaddrout);
  566. return err;
  567. }
  568. static int compat_get_fastrpc_ioctl_munmap(
  569. struct compat_fastrpc_ioctl_munmap __user *unmap32,
  570. struct fastrpc_ioctl_munmap __user *unmap)
  571. {
  572. compat_uptr_t p;
  573. compat_size_t s;
  574. int err;
  575. err = get_user(p, &unmap32->vaddrout);
  576. memcpy(&unmap->vaddrout, &p, sizeof(p));
  577. err |= get_user(s, &unmap32->size);
  578. memcpy(&unmap->size, &s, sizeof(s));
  579. return err;
  580. }
  581. static int compat_get_fastrpc_ioctl_munmap_64(
  582. struct compat_fastrpc_ioctl_munmap_64 __user *unmap32,
  583. struct fastrpc_ioctl_munmap *unmap)
  584. {
  585. compat_u64 p;
  586. compat_size_t s;
  587. int err;
  588. err = get_user(p, &unmap32->vaddrout);
  589. memcpy(&unmap->vaddrout, &p, sizeof(p));
  590. err |= get_user(s, &unmap32->size);
  591. memcpy(&unmap->size, &s, sizeof(s));
  592. return err;
  593. }
  594. static int compat_get_fastrpc_ioctl_control(
  595. struct compat_fastrpc_ioctl_control __user *ctrl32,
  596. struct fastrpc_ioctl_control *ctrl)
  597. {
  598. compat_uptr_t p;
  599. int err;
  600. err = get_user(p, &ctrl32->req);
  601. memcpy(&ctrl->req, &p, sizeof(p));
  602. if ((p == FASTRPC_CONTROL_LATENCY) || (p == FASTRPC_CONTROL_RPC_POLL)) {
  603. err |= get_user(p, &ctrl32->lp.enable);
  604. memcpy(&ctrl->lp.enable, &p, sizeof(p));
  605. err |= get_user(p, &ctrl32->lp.latency);
  606. memcpy(&ctrl->lp.latency, &p, sizeof(p));
  607. } else if (p == FASTRPC_CONTROL_WAKELOCK) {
  608. err |= get_user(p, &ctrl32->wp.enable);
  609. memcpy(&ctrl->wp.enable, &p, sizeof(p));
  610. } else if (p == FASTRPC_CONTROL_PM) {
  611. err |= get_user(p, &ctrl32->pm.timeout);
  612. memcpy(&ctrl->pm.timeout, &p, sizeof(p));
  613. }
  614. return err;
  615. }
  616. static int compat_get_fastrpc_ioctl_init(
  617. struct compat_fastrpc_ioctl_init_attrs __user *init32,
  618. struct fastrpc_ioctl_init_attrs *init,
  619. unsigned int cmd)
  620. {
  621. compat_uint_t u;
  622. compat_uptr_t p;
  623. compat_int_t i;
  624. int err;
  625. err = get_user(u, &init32->init.flags);
  626. memcpy(&init->init.flags, &u, sizeof(u));
  627. err |= get_user(p, &init32->init.file);
  628. memcpy(&init->init.file, &p, sizeof(p));
  629. err |= get_user(i, &init32->init.filelen);
  630. memcpy(&init->init.filelen, &i, sizeof(i));
  631. err |= get_user(i, &init32->init.filefd);
  632. memcpy(&init->init.filefd, &i, sizeof(i));
  633. err |= get_user(p, &init32->init.mem);
  634. memcpy(&init->init.mem, &p, sizeof(p));
  635. err |= get_user(i, &init32->init.memlen);
  636. memcpy(&init->init.memlen, &i, sizeof(i));
  637. err |= get_user(i, &init32->init.memfd);
  638. memcpy(&init->init.memfd, &i, sizeof(i));
  639. init->attrs = 0;
  640. if (cmd == COMPAT_FASTRPC_IOCTL_INIT_ATTRS) {
  641. err |= get_user(i, &init32->attrs);
  642. memcpy((compat_uptr_t *)&init->attrs, &i, sizeof(i));
  643. }
  644. init->siglen = 0;
  645. if (cmd == COMPAT_FASTRPC_IOCTL_INIT_ATTRS) {
  646. err |= get_user(i, &init32->siglen);
  647. memcpy((compat_uptr_t *)&init->siglen, &i, sizeof(i));
  648. }
  649. return err;
  650. }
  651. static int compat_put_fastrpc_ioctl_get_dsp_info(
  652. struct compat_fastrpc_ioctl_capability __user *info32,
  653. struct fastrpc_ioctl_capability __user *info)
  654. {
  655. compat_uint_t u;
  656. int err = 0;
  657. memcpy(&u, &info->capability, sizeof(u));
  658. err |= put_user(u, &info32->capability);
  659. return err;
  660. }
  661. static int compat_fastrpc_control(struct fastrpc_file *fl,
  662. unsigned long arg)
  663. {
  664. int err = 0;
  665. struct compat_fastrpc_ioctl_control __user *ctrl32;
  666. struct fastrpc_ioctl_control *ctrl = NULL;
  667. compat_uptr_t p;
  668. ctrl32 = compat_ptr(arg);
  669. VERIFY(err, NULL != (ctrl = kmalloc(
  670. sizeof(*ctrl), GFP_KERNEL)));
  671. if (err)
  672. return -EFAULT;
  673. VERIFY(err, 0 == compat_get_fastrpc_ioctl_control(ctrl32,
  674. ctrl));
  675. if (err)
  676. goto bail;
  677. VERIFY(err, 0 == (err = fastrpc_internal_control(fl, ctrl)));
  678. if (err)
  679. goto bail;
  680. err = get_user(p, &ctrl32->req);
  681. if (err)
  682. goto bail;
  683. if (p == FASTRPC_CONTROL_KALLOC) {
  684. memcpy(&p, &ctrl->kalloc.kalloc_support, sizeof(ctrl->kalloc.kalloc_support));
  685. err |= put_user(p, &ctrl32->kalloc.kalloc_support);
  686. }
  687. bail:
  688. kfree(ctrl);
  689. return err;
  690. }
  691. static int compat_fastrpc_get_dsp_info(struct fastrpc_file *fl,
  692. unsigned long arg)
  693. {
  694. struct compat_fastrpc_ioctl_capability __user *info32 = NULL;
  695. struct fastrpc_ioctl_capability *info = NULL;
  696. compat_uint_t u;
  697. int err = 0;
  698. size_t info_size = 0;
  699. info32 = compat_ptr(arg);
  700. VERIFY(err, NULL != (info = kmalloc(
  701. sizeof(*info), GFP_KERNEL)));
  702. info_size = sizeof(*info);
  703. if (err) {
  704. ADSPRPC_ERR("allocation failed for size 0x%zx\n", info_size);
  705. return err;
  706. }
  707. err = get_user(u, &info32->domain);
  708. if (err)
  709. goto bail;
  710. memcpy(&info->domain, &u, sizeof(info->domain));
  711. err = get_user(u, &info32->attribute_ID);
  712. if (err)
  713. goto bail;
  714. memcpy(&info->attribute_ID, &u, sizeof(info->attribute_ID));
  715. err = fastrpc_get_info_from_kernel(info, fl);
  716. if (err)
  717. goto bail;
  718. err = compat_put_fastrpc_ioctl_get_dsp_info(info32, info);
  719. bail:
  720. kfree(info);
  721. return err;
  722. }
  723. static inline long compat_fastrpc_mmap_device_ioctl(struct fastrpc_file *fl,
  724. unsigned int cmd, unsigned long arg)
  725. {
  726. int err = 0;
  727. switch (cmd) {
  728. case COMPAT_FASTRPC_IOCTL_MEM_MAP:
  729. {
  730. struct compat_fastrpc_ioctl_mem_map __user *map32;
  731. struct fastrpc_ioctl_mem_map *map = NULL;
  732. map32 = compat_ptr(arg);
  733. VERIFY(err, NULL != (map = kmalloc(
  734. sizeof(*map), GFP_KERNEL)));
  735. if (err)
  736. return -EFAULT;
  737. err = compat_get_fastrpc_ioctl_mem_map(map32, map);
  738. if (err) {
  739. kfree(map);
  740. return err;
  741. }
  742. VERIFY(err, 0 == (err = fastrpc_internal_mem_map(fl,
  743. map)));
  744. if (err) {
  745. kfree(map);
  746. return err;
  747. }
  748. VERIFY(err, 0 == compat_put_fastrpc_ioctl_mem_map(map32, map));
  749. kfree(map);
  750. return err;
  751. }
  752. case COMPAT_FASTRPC_IOCTL_MEM_UNMAP:
  753. {
  754. struct compat_fastrpc_ioctl_mem_unmap __user *unmap32;
  755. struct fastrpc_ioctl_mem_unmap *unmap = NULL;
  756. unmap32 = compat_ptr(arg);
  757. unmap = kmalloc(sizeof(*unmap), GFP_KERNEL);
  758. if (unmap == NULL)
  759. return -EFAULT;
  760. err = compat_get_fastrpc_ioctl_mem_unmap(unmap32, unmap);
  761. if (err) {
  762. kfree(unmap);
  763. return err;
  764. }
  765. VERIFY(err, 0 == (err = fastrpc_internal_mem_unmap(fl,
  766. unmap)));
  767. kfree(unmap);
  768. return err;
  769. }
  770. case COMPAT_FASTRPC_IOCTL_MMAP:
  771. {
  772. struct compat_fastrpc_ioctl_mmap __user *map32;
  773. struct fastrpc_ioctl_mmap *map = NULL;
  774. map32 = compat_ptr(arg);
  775. VERIFY(err, NULL != (map = kmalloc(
  776. sizeof(*map), GFP_KERNEL)));
  777. if (err)
  778. return -EFAULT;
  779. VERIFY(err, 0 == compat_get_fastrpc_ioctl_mmap(map32, map));
  780. if (err) {
  781. kfree(map);
  782. return err;
  783. }
  784. VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, map)));
  785. VERIFY(err, 0 == compat_put_fastrpc_ioctl_mmap(map32, map));
  786. kfree(map);
  787. return err;
  788. }
  789. case COMPAT_FASTRPC_IOCTL_MMAP_64:
  790. {
  791. struct compat_fastrpc_ioctl_mmap_64 __user *map32;
  792. struct fastrpc_ioctl_mmap *map = NULL;
  793. map32 = compat_ptr(arg);
  794. VERIFY(err, NULL != (map = kmalloc(
  795. sizeof(*map), GFP_KERNEL)));
  796. if (err)
  797. return -EFAULT;
  798. VERIFY(err, 0 == compat_get_fastrpc_ioctl_mmap_64(map32, map));
  799. if (err) {
  800. kfree(map);
  801. return err;
  802. }
  803. VERIFY(err, 0 == (err = fastrpc_internal_mmap(fl, map)));
  804. VERIFY(err, 0 == compat_put_fastrpc_ioctl_mmap_64(map32, map));
  805. kfree(map);
  806. return err;
  807. }
  808. case COMPAT_FASTRPC_IOCTL_MUNMAP:
  809. {
  810. struct compat_fastrpc_ioctl_munmap __user *unmap32;
  811. struct fastrpc_ioctl_munmap *unmap = NULL;
  812. unmap32 = compat_ptr(arg);
  813. VERIFY(err, NULL != (unmap = kmalloc(
  814. sizeof(*unmap), GFP_KERNEL)));
  815. if (err)
  816. return -EFAULT;
  817. VERIFY(err, 0 == compat_get_fastrpc_ioctl_munmap(unmap32,
  818. unmap));
  819. if (err) {
  820. kfree(unmap);
  821. return err;
  822. }
  823. VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
  824. unmap)));
  825. kfree(unmap);
  826. return err;
  827. }
  828. default:
  829. return -ENOIOCTLCMD;
  830. }
  831. }
  832. static long compat_fastrpc_dspsignal_create(struct fastrpc_file *fl, unsigned long arg)
  833. {
  834. struct fastrpc_ioctl_dspsignal_create __user *uc = compat_ptr(arg);
  835. struct fastrpc_ioctl_dspsignal_create c;
  836. int err = 0;
  837. err = copy_from_user(&c, uc, sizeof(c));
  838. if (err)
  839. return -EFAULT;
  840. return fastrpc_dspsignal_create(fl, &c);
  841. }
  842. static long compat_fastrpc_dspsignal_destroy(struct fastrpc_file *fl, unsigned long arg)
  843. {
  844. struct fastrpc_ioctl_dspsignal_destroy __user *uc = compat_ptr(arg);
  845. struct fastrpc_ioctl_dspsignal_destroy c;
  846. int err = 0;
  847. err = copy_from_user(&c, uc, sizeof(c));
  848. if (err)
  849. return -EFAULT;
  850. return fastrpc_dspsignal_destroy(fl, &c);
  851. }
  852. static long compat_fastrpc_dspsignal_signal(struct fastrpc_file *fl, unsigned long arg)
  853. {
  854. struct fastrpc_ioctl_dspsignal_signal __user *uc = compat_ptr(arg);
  855. struct fastrpc_ioctl_dspsignal_signal c;
  856. int err = 0;
  857. err = copy_from_user(&c, uc, sizeof(c));
  858. if (err)
  859. return -EFAULT;
  860. return fastrpc_dspsignal_signal(fl, &c);
  861. }
  862. static long compat_fastrpc_dspsignal_wait(struct fastrpc_file *fl, unsigned long arg)
  863. {
  864. struct fastrpc_ioctl_dspsignal_wait __user *uc = compat_ptr(arg);
  865. struct fastrpc_ioctl_dspsignal_wait c;
  866. int err = 0;
  867. err = copy_from_user(&c, uc, sizeof(c));
  868. if (err)
  869. return -EFAULT;
  870. return fastrpc_dspsignal_wait(fl, &c);
  871. }
  872. static long compat_fastrpc_dspsignal_cancel_wait(struct fastrpc_file *fl, unsigned long arg)
  873. {
  874. struct fastrpc_ioctl_dspsignal_cancel_wait __user *uc = compat_ptr(arg);
  875. struct fastrpc_ioctl_dspsignal_cancel_wait c;
  876. int err = 0;
  877. err = copy_from_user(&c, uc, sizeof(c));
  878. if (err)
  879. return -EFAULT;
  880. return fastrpc_dspsignal_cancel_wait(fl, &c);
  881. }
  882. long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
  883. unsigned long arg)
  884. {
  885. int err = 0;
  886. struct fastrpc_file *fl = (struct fastrpc_file *)filp->private_data;
  887. if (!filp->f_op || !filp->f_op->unlocked_ioctl)
  888. return -ENOTTY;
  889. switch (cmd) {
  890. case COMPAT_FASTRPC_IOCTL_INVOKE:
  891. case COMPAT_FASTRPC_IOCTL_INVOKE_FD:
  892. case COMPAT_FASTRPC_IOCTL_INVOKE_ATTRS:
  893. case COMPAT_FASTRPC_IOCTL_INVOKE_CRC:
  894. case COMPAT_FASTRPC_IOCTL_INVOKE_PERF:
  895. {
  896. return compat_fastrpc_ioctl_invoke(filp, cmd, arg);
  897. }
  898. case COMPAT_FASTRPC_IOCTL_INVOKE2:
  899. {
  900. return compat_fastrpc_ioctl_invoke2(filp, cmd, arg);
  901. }
  902. case COMPAT_FASTRPC_IOCTL_MUNMAP_64:
  903. {
  904. struct compat_fastrpc_ioctl_munmap_64 __user *unmap32;
  905. struct fastrpc_ioctl_munmap *unmap = NULL;
  906. unmap32 = compat_ptr(arg);
  907. VERIFY(err, NULL != (unmap = kmalloc(
  908. sizeof(*unmap), GFP_KERNEL)));
  909. if (err)
  910. return -EFAULT;
  911. VERIFY(err, 0 == compat_get_fastrpc_ioctl_munmap_64(unmap32,
  912. unmap));
  913. if (err) {
  914. kfree(unmap);
  915. return err;
  916. }
  917. VERIFY(err, 0 == (err = fastrpc_internal_munmap(fl,
  918. unmap)));
  919. kfree(unmap);
  920. return err;
  921. }
  922. case COMPAT_FASTRPC_IOCTL_INIT:
  923. fallthrough;
  924. case COMPAT_FASTRPC_IOCTL_INIT_ATTRS:
  925. {
  926. struct compat_fastrpc_ioctl_init_attrs __user *init32;
  927. struct fastrpc_ioctl_init_attrs *init = NULL;
  928. init32 = compat_ptr(arg);
  929. VERIFY(err, NULL != (init = kmalloc(
  930. sizeof(*init), GFP_KERNEL)));
  931. if (err)
  932. return -EFAULT;
  933. VERIFY(err, 0 == compat_get_fastrpc_ioctl_init(init32,
  934. init, cmd));
  935. if (err) {
  936. kfree(init);
  937. return err;
  938. }
  939. VERIFY(err, 0 == (err = fastrpc_init_process(fl, init)));
  940. kfree(init);
  941. return err;
  942. }
  943. case FASTRPC_IOCTL_GETINFO:
  944. {
  945. compat_uptr_t __user *info32;
  946. uint32_t *info = NULL;
  947. compat_uint_t u;
  948. info32 = compat_ptr(arg);
  949. VERIFY(err, NULL != (info = kmalloc(
  950. sizeof(*info), GFP_KERNEL)));
  951. if (err)
  952. return -EFAULT;
  953. err = get_user(u, info32);
  954. memcpy(info, &u, sizeof(u));
  955. if (err) {
  956. kfree(info);
  957. return err;
  958. }
  959. VERIFY(err, 0 == (err = fastrpc_get_info(fl, info)));
  960. memcpy(&u, info, sizeof(*info));
  961. err |= put_user(u, info32);
  962. kfree(info);
  963. return err;
  964. }
  965. case FASTRPC_IOCTL_SETMODE:
  966. return fastrpc_setmode(arg, fl);
  967. case COMPAT_FASTRPC_IOCTL_CONTROL:
  968. {
  969. return compat_fastrpc_control(fl, arg);
  970. }
  971. case COMPAT_FASTRPC_IOCTL_GET_DSP_INFO:
  972. {
  973. return compat_fastrpc_get_dsp_info(fl, arg);
  974. }
  975. case COMPAT_FASTRPC_IOCTL_MEM_MAP:
  976. fallthrough;
  977. case COMPAT_FASTRPC_IOCTL_MEM_UNMAP:
  978. fallthrough;
  979. case COMPAT_FASTRPC_IOCTL_MMAP:
  980. fallthrough;
  981. case COMPAT_FASTRPC_IOCTL_MMAP_64:
  982. fallthrough;
  983. case COMPAT_FASTRPC_IOCTL_MUNMAP:
  984. return compat_fastrpc_mmap_device_ioctl(fl, cmd, arg);
  985. case COMPAT_FASTRPC_IOCTL_DSPSIGNAL_CREATE:
  986. return compat_fastrpc_dspsignal_create(fl, arg);
  987. case COMPAT_FASTRPC_IOCTL_DSPSIGNAL_DESTROY:
  988. return compat_fastrpc_dspsignal_destroy(fl, arg);
  989. case COMPAT_FASTRPC_IOCTL_DSPSIGNAL_SIGNAL:
  990. return compat_fastrpc_dspsignal_signal(fl, arg);
  991. case COMPAT_FASTRPC_IOCTL_DSPSIGNAL_WAIT:
  992. return compat_fastrpc_dspsignal_wait(fl, arg);
  993. case COMPAT_FASTRPC_IOCTL_DSPSIGNAL_CANCEL_WAIT:
  994. return compat_fastrpc_dspsignal_cancel_wait(fl, arg);
  995. default:
  996. return -ENOTTY;
  997. }
  998. }