1 /*
2 * Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12 #include <chcore/syscall.h>
13 #include <unistd.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <chcore-internal/chanmgr_defs.h>
18 #include <chcore-internal/procmgr_defs.h>
19 #include <chcore/ipc.h>
20 #include <chcore/container/hashtable.h>
21 #include <pthread.h>
22
23 #include <ipclib.h>
24
25 #define ipc_info(fmt, ...) \
26 printf("%s %d: " fmt, __func__, __LINE__, ##__VA_ARGS__)
27
28 struct __ipc_tls_st {
29 ipc_struct_t *chanmgr_ipc_struct;
30 int channel[2];
31 int msg_hdl;
32 };
33 static struct __ipc_tls_st __ipc_tls__[1024];
34
35 #define __ipc_tls (__ipc_tls__[gettid()])
36
37 /* attain chanmgr ipc_struct */
__conn_server(void)38 static ipc_struct_t *__conn_server(void)
39 {
40 cap_t server_cap;
41 ipc_msg_t *ipc_msg;
42 struct proc_request *req;
43 ipc_struct_t *cis = NULL;
44 int ret;
45
46 ipc_msg = ipc_create_msg(procmgr_ipc_struct, sizeof(struct proc_request));
47 req = (struct proc_request *)ipc_get_msg_data(ipc_msg);
48 req->req = PROC_REQ_GET_SERVER_CAP;
49 req->get_server_cap.server_id = SERVER_CHANMGR;
50 ret = ipc_call(procmgr_ipc_struct, ipc_msg);
51 if (ret != 0) {
52 goto out;
53 }
54
55 server_cap = ipc_get_msg_cap(ipc_msg, 0);
56 if (server_cap < 0) {
57 ret = -1;
58 goto out;
59 }
60
61 do {
62 cis = ipc_register_client(server_cap);
63 usys_yield();
64 } while (cis == NULL);
65
66 out:
67 ipc_destroy_msg(ipc_msg);
68 return cis;
69 }
70
71 /* per-thread chanmgr ipc_struct */
__chanmgr_ipc_struct(void)72 static ipc_struct_t *__chanmgr_ipc_struct(void)
73 {
74 if (__ipc_tls.chanmgr_ipc_struct == NULL) {
75 __ipc_tls.chanmgr_ipc_struct = __conn_server();
76 }
77
78 return __ipc_tls.chanmgr_ipc_struct;
79 }
80
81 #define chanmgr_ipc_struct (__chanmgr_ipc_struct())
82
__ipc_util_create_channel(const char * name,int ch_num,int channel,struct reg_items_st reg_items)83 static int __ipc_util_create_channel(const char *name, int ch_num, int channel,
84 struct reg_items_st reg_items)
85 {
86 ipc_msg_t *ipc_msg;
87 struct chan_request *req;
88 int ret;
89
90 ipc_msg = ipc_create_msg_with_cap(
91 chanmgr_ipc_struct, sizeof(struct chan_request), 1);
92 req = (struct chan_request *)ipc_get_msg_data(ipc_msg);
93 req->req = CHAN_REQ_CREATE_CHANNEL;
94 ret = ipc_set_msg_cap(ipc_msg, 0, channel);
95 if (ret < 0) {
96 ret = -EINVAL;
97 goto out_fail;
98 }
99
100 memset(req->create_channel.name, 0, sizeof(req->create_channel.name));
101 if (name != NULL && (reg_items.reg_name || reg_items.reg_tamgr)) {
102 if (strlen(name) >= CHAN_REQ_NAME_LEN) {
103 ret = -ENAMETOOLONG;
104 goto out_fail;
105 }
106 memcpy(req->create_channel.name, name, strlen(name));
107 }
108 if (reg_items.reg_pid) {
109 req->create_channel.ch_num = ch_num;
110 }
111 memcpy(&req->create_channel.reg_items,
112 ®_items,
113 sizeof(struct reg_items_st));
114
115 ret = ipc_call(chanmgr_ipc_struct, ipc_msg);
116
117 out_fail:
118 ipc_destroy_msg(ipc_msg);
119
120 return ret;
121 }
122
__ipc_util_remove_channel(const char * name,int ch_num,uint32_t taskid)123 static int __ipc_util_remove_channel(const char *name, int ch_num,
124 uint32_t taskid)
125 {
126 ipc_msg_t *ipc_msg;
127 struct chan_request *req;
128 int ret;
129
130 if (taskid == 0) {
131 taskid = get_self_taskid();
132 }
133
134 ipc_msg = ipc_create_msg(chanmgr_ipc_struct, sizeof(struct chan_request));
135 req = (struct chan_request *)ipc_get_msg_data(ipc_msg);
136 req->req = CHAN_REQ_REMOVE_CHANNEL;
137
138 memset(req->remove_channel.name, 0, sizeof(req->remove_channel.name));
139 if (name) {
140 if (strlen(name) >= CHAN_REQ_NAME_LEN) {
141 ret = -ENAMETOOLONG;
142 goto out_fail;
143 }
144 memcpy(req->remove_channel.name, name, strlen(name));
145 }
146 if (ch_num == 0 || ch_num == 1) {
147 req->remove_channel.taskid = taskid;
148 req->remove_channel.ch_num = ch_num;
149 }
150
151 ret = ipc_call(chanmgr_ipc_struct, ipc_msg);
152
153 out_fail:
154 ipc_destroy_msg(ipc_msg);
155
156 return ret;
157 }
158
__ipc_util_hunt_by_name(const char * name,uint32_t * taskid)159 static int __ipc_util_hunt_by_name(const char *name, uint32_t *taskid)
160 {
161 ipc_msg_t *ipc_msg;
162 struct chan_request *req;
163 int ret;
164
165 ipc_msg = ipc_create_msg(chanmgr_ipc_struct, sizeof(struct chan_request));
166 req = (struct chan_request *)ipc_get_msg_data(ipc_msg);
167 req->req = CHAN_REQ_HUNT_BY_NAME;
168
169 if (name == NULL) {
170 ret = -EINVAL;
171 goto out_fail;
172 }
173 if (strlen(name) >= CHAN_REQ_NAME_LEN) {
174 ret = -ENAMETOOLONG;
175 goto out_fail;
176 }
177
178 memset(req->hunt_by_name.name, 0, sizeof(req->hunt_by_name.name));
179 memcpy(req->hunt_by_name.name, name, strlen(name));
180 ret = ipc_call(chanmgr_ipc_struct, ipc_msg);
181 if (ret == 0) {
182 *taskid = req->hunt_by_name.taskid;
183 }
184
185 out_fail:
186 ipc_destroy_msg(ipc_msg);
187
188 return ret;
189 }
190
__ipc_util_get_ch_from_path(const char * name,int * cap)191 static int __ipc_util_get_ch_from_path(const char *name, int *cap)
192 {
193 ipc_msg_t *ipc_msg;
194 struct chan_request *req;
195 int ret;
196
197 ipc_msg = ipc_create_msg(chanmgr_ipc_struct, sizeof(struct chan_request));
198 req = (struct chan_request *)ipc_get_msg_data(ipc_msg);
199 req->req = CHAN_REQ_GET_CH_FROM_PATH;
200
201 if (name == NULL) {
202 ret = -EINVAL;
203 goto out_fail;
204 }
205 if (strlen(name) >= CHAN_REQ_NAME_LEN) {
206 ret = -ENAMETOOLONG;
207 goto out_fail;
208 }
209
210 memset(req->get_ch_from_path.name, 0, sizeof(req->get_ch_from_path.name));
211 memcpy(req->get_ch_from_path.name, name, strlen(name));
212 ret = ipc_call(chanmgr_ipc_struct, ipc_msg);
213 if (ret == 0) {
214 ret = ipc_get_msg_cap(ipc_msg, 0);
215 if (ret < 0) {
216 ret = -EINVAL;
217 } else {
218 *cap = ret;
219 ret = 0;
220 }
221 }
222
223 out_fail:
224 ipc_destroy_msg(ipc_msg);
225
226 return ret;
227 }
228
__ipc_util_get_ch_from_taskid(uint32_t taskid,int ch_num,int * cap)229 static int __ipc_util_get_ch_from_taskid(uint32_t taskid, int ch_num, int *cap)
230 {
231 ipc_msg_t *ipc_msg;
232 struct chan_request *req;
233 int ret;
234
235 ipc_msg = ipc_create_msg(chanmgr_ipc_struct, sizeof(struct chan_request));
236 req = (struct chan_request *)ipc_get_msg_data(ipc_msg);
237 req->req = CHAN_REQ_GET_CH_FROM_TASKID;
238
239 req->get_ch_from_taskid.taskid = taskid;
240 req->get_ch_from_taskid.ch_num = ch_num;
241 ret = ipc_call(chanmgr_ipc_struct, ipc_msg);
242 if (ret == 0) {
243 ret = ipc_get_msg_cap(ipc_msg, 0);
244 if (ret < 0) {
245 ret = -EINVAL;
246 } else {
247 *cap = ret;
248 ret = 0;
249 }
250 }
251
252 ipc_destroy_msg(ipc_msg);
253
254 return ret;
255 }
256
__ipc_util_register_tamgr(const char * name)257 static int __ipc_util_register_tamgr(const char *name)
258 {
259 ipc_msg_t *ipc_msg;
260 struct chan_request *req;
261 int ret;
262
263 ipc_msg = ipc_create_msg(chanmgr_ipc_struct, sizeof(struct chan_request));
264 req = (struct chan_request *)ipc_get_msg_data(ipc_msg);
265 req->req = CHAN_REQ_REGISTER_TAMGR;
266
267 if (strlen(name) >= CHAN_REQ_NAME_LEN) {
268 ret = -ENAMETOOLONG;
269 goto out;
270 }
271 memcpy(req->register_tamgr.name, name, strlen(name) + 1);
272
273 ret = ipc_call(chanmgr_ipc_struct, ipc_msg);
274 ipc_destroy_msg(ipc_msg);
275
276 out:
277 return ret;
278 }
279
280 #define HTABLE_SIZE 1024
281
282 struct task2capmgr {
283 pthread_mutex_t lock;
284 struct htable table;
285 volatile int initialized;
286 };
287
__task2cap(void)288 static struct task2capmgr *__task2cap(void)
289 {
290 static struct task2capmgr task2cap_table = {.initialized = 0};
291 int old;
292
293 old = __sync_val_compare_and_swap(&task2cap_table.initialized, 0, 1);
294 if (old == 0) {
295 init_htable(&task2cap_table.table, HTABLE_SIZE);
296 pthread_mutex_init(&task2cap_table.lock, NULL);
297 }
298 return &task2cap_table;
299 }
300
301 #define task2cap (__task2cap())
302
303 struct task2cap_ent {
304 struct hlist_node task2cap_node;
305 cap_t cap;
306 taskid_t taskid;
307 int ch_num;
308 };
309
__get_entry(taskid_t taskid,int ch_num)310 static struct task2cap_ent *__get_entry(taskid_t taskid, int ch_num)
311 {
312 struct task2cap_ent *entry;
313 struct hlist_head *bucket;
314
315 bucket = htable_get_bucket(&task2cap->table, taskid);
316 for_each_in_hlist (entry, task2cap_node, bucket) {
317 if (entry->taskid == taskid && entry->ch_num == ch_num) {
318 return entry;
319 }
320 }
321
322 return NULL;
323 }
324
325 /*
326 * Create channel(s) and register mapping info among name, taskid and channel
327 * @name: channel's name
328 * @ch_cnt: the number(1 or 2) of channel(s) to be created
329 * @pp_ch: output the cap(s) of corresponding channel(s)
330 * @reg_items: guidance on specific registration behaviors
331 *
332 * Create ch_cnt channel(s).
333 * if reg_items.reg_name is true and name is not NULL:
334 * register (name, channel[0]) mapping info into chanmgr
335 * if reg_items.reg_tamgr is true and name is not NULL:
336 * register (name, taskid) mapping info into chanmgr
337 * if reg_items.reg_pid is true:
338 * register ((taskid, ch_num), channel) mapping info into chanmgr
339 * save channel cap(s) into pthread struct
340 * Return:
341 * 0: success
342 * errno: fail
343 */
ipc_create_channel(const char * name,int32_t ch_cnt,cref_t * pp_ch[],struct reg_items_st reg_items)344 int32_t ipc_create_channel(const char *name, int32_t ch_cnt, cref_t *pp_ch[],
345 struct reg_items_st reg_items)
346 {
347 int ret, i;
348 cap_t chan[2];
349
350 if (name && reg_items.reg_tamgr) {
351 ret = __ipc_util_register_tamgr(name);
352 if (ret < 0)
353 goto out_fail;
354 reg_items.reg_tamgr = false;
355 }
356
357 if (!reg_items.reg_tamgr && !reg_items.reg_pid && !reg_items.reg_name) {
358 ret = 0;
359 goto out_fail;
360 }
361
362 if (!(ch_cnt > 0 && ch_cnt <= CH_CNT_MAX)) {
363 ret = -EINVAL;
364 goto out_fail;
365 }
366
367 for (i = 0; i < ch_cnt; i++) {
368 ret = usys_tee_msg_create_channel();
369 if (ret < 0) {
370 goto out_free_channel;
371 }
372 chan[i] = ret;
373 }
374
375 /* remove old local channels if reg_pid */
376 if (reg_items.reg_pid && __ipc_tls.channel[0] != 0) {
377 ipc_remove_channel(0, NULL, 0, 0);
378 }
379 ret = __ipc_util_create_channel(name, 0, chan[0], reg_items);
380 if (ret < 0) {
381 goto out_free_channel;
382 }
383 if (ch_cnt == CH_CNT_MAX) {
384 if (reg_items.reg_pid && __ipc_tls.channel[1] != 0) {
385 ipc_remove_channel(0, NULL, 1, 0);
386 }
387 ret = __ipc_util_create_channel(NULL, 1, chan[1], reg_items);
388 if (ret < 0) {
389 goto out_remove_first_channel;
390 }
391 }
392
393 for (i = 0; i < ch_cnt; i++) {
394 if (reg_items.reg_pid) {
395 __ipc_tls.channel[i] = chan[i];
396 }
397 if (pp_ch) {
398 *pp_ch[i] = chan[i];
399 }
400 }
401
402 return 0;
403
404 out_remove_first_channel:
405 __ipc_util_remove_channel(name, 0, 0);
406
407 out_free_channel:
408 for (i = i - 1; i >= 0; i--) {
409 usys_revoke_cap(chan[i], false);
410 }
411
412 out_fail:
413 return ret;
414 }
415
416 /*
417 * Remove channel(s) and deregister mapping info among name, taskid and channel
418 * @task_id: taskid in ((taskid, ch_num), channel) mapping info
419 * @name: name in (name, channel) & (name, taskid) mapping info
420 * @ch_num: ch_num in ((taskid, ch_num), channel) mapping info & which channel
421 * in pthread struct to be removed
422 * @ch: channel cap
423 *
424 * if name is not NULL:
425 * deregister (name, channel) and (name, taskid) mapping info in chanmgr if
426 * exist deregister ((taskid, ch_num), channel) mapping info in chanmgr if exist
427 * if ch is 0, remove the ch_numth channel in pthread struct
428 * else, remove ch
429 * Return:
430 * 0: success
431 * errno: fail
432 */
ipc_remove_channel(uint32_t task_id,const char * name,int32_t ch_num,cref_t ch)433 int32_t ipc_remove_channel(uint32_t task_id, const char *name, int32_t ch_num,
434 cref_t ch)
435 {
436 int ret;
437
438 if (task_id == 0) {
439 task_id = get_self_taskid();
440 }
441
442 if (ch == 0) {
443 if (ch_num == 0 || ch_num == 1) {
444 ch = __ipc_tls.channel[ch_num];
445 } else {
446 return -EINVAL;
447 }
448 }
449
450 ret = __ipc_util_remove_channel(name, ch_num, task_id);
451 if (ret != 0) {
452 goto out;
453 }
454
455 ret = usys_tee_msg_stop_channel(ch);
456 if (ret != 0) {
457 goto out;
458 }
459
460 if ((ch_num == 0 || ch_num == 1) && task_id == get_self_taskid()) {
461 __ipc_tls.channel[ch_num] = 0;
462 }
463
464 ret = usys_revoke_cap(ch, false);
465
466 out:
467 return ret;
468 }
469
470 /*
471 * Release channel reference cap from path.
472 * @path: not used in ChCore
473 * @rref: channel cap
474 *
475 * Revoke the channel cap directly.
476 * Return:
477 * 0: success
478 * errno: fail
479 */
ipc_release_from_path(const char * path,cref_t rref)480 uint32_t ipc_release_from_path(const char *path, cref_t rref)
481 {
482 int ret;
483
484 ret = usys_revoke_cap(rref, false);
485
486 return ret;
487 }
488
489 /*
490 * Release channel reference cap from task_id.
491 *
492 * Revoke the corresponding channel cap.
493 * Return:
494 * 0: success
495 * errno: fail
496 */
ipc_release_from_taskid(uint32_t task_id,int32_t ch_num)497 uint32_t ipc_release_from_taskid(uint32_t task_id, int32_t ch_num)
498 {
499 int ret = 0;
500 struct task2cap_ent *entry;
501
502 pthread_mutex_lock(&task2cap->lock);
503
504 entry = __get_entry(task_id, ch_num);
505 if (entry == NULL) {
506 ret = -ENOENT;
507 goto out;
508 }
509
510 usys_revoke_cap(entry->cap, false);
511 htable_del(&entry->task2cap_node);
512 free(entry);
513
514 out:
515 pthread_mutex_unlock(&task2cap->lock);
516 return ret;
517 }
518
ipc_release_by_name(const char * name)519 uint32_t ipc_release_by_name(const char *name)
520 {
521 return 0;
522 }
523
524 /*
525 * Get channel cap from chanmgr, which can be indexed through channel name.
526 * @name: name of the channel
527 * @p_ch: output the cap of the channel
528 *
529 * Send ChCore IPC request to chanmgr to get channel cap.
530 * Return:
531 * 0: success
532 * errno: fail
533 */
ipc_get_ch_from_path(const char * name,cref_t * p_ch)534 int32_t ipc_get_ch_from_path(const char *name, cref_t *p_ch)
535 {
536 int ret;
537
538 ret = __ipc_util_get_ch_from_path(name, p_ch);
539
540 return ret;
541 }
542
543 /*
544 * Get channel cap from chanmgr, which can be indexed through (taskid, ch_num).
545 * @taskid: taskid in ((taskid, ch_num), channel) mapping info
546 * @ch_num: ch_num in ((taskid, ch_num), channel) mapping info
547 * @p_ch: output the cap of the channel
548 *
549 * Send ChCore IPC request to chanmgr to get channel cap.
550 * Return:
551 * 0: success
552 * errno: fail
553 */
ipc_get_ch_from_taskid(uint32_t taskid,int32_t ch_num,cref_t * p_ch)554 int32_t ipc_get_ch_from_taskid(uint32_t taskid, int32_t ch_num, cref_t *p_ch)
555 {
556 int ret;
557 struct task2cap_ent *entry;
558
559 pthread_mutex_lock(&task2cap->lock);
560
561 entry = __get_entry(taskid, ch_num);
562 if (entry != NULL) {
563 *p_ch = entry->cap;
564 ret = 0;
565 goto out;
566 }
567
568 entry = malloc(sizeof(*entry));
569 if (entry == NULL) {
570 ret = -ENOMEM;
571 goto out;
572 }
573
574 ret = __ipc_util_get_ch_from_taskid(taskid, ch_num, p_ch);
575 if (ret != 0) {
576 goto out_free_entry;
577 }
578
579 entry->taskid = taskid;
580 entry->ch_num = ch_num;
581 entry->cap = *p_ch;
582 init_hlist_node(&entry->task2cap_node);
583 htable_add(&task2cap->table, taskid, &entry->task2cap_node);
584
585 pthread_mutex_unlock(&task2cap->lock);
586 return 0;
587
588 out_free_entry:
589 free(entry);
590 out:
591 pthread_mutex_unlock(&task2cap->lock);
592 return ret;
593 }
594
595 /*
596 * Get server's taskid from chanmgr, which can be indexed through name.
597 * @name: name of the channel
598 * @task_id: output the taskid of the server who created the channel named @name
599 *
600 * Send ChCore IPC request to chanmgr to get taskid.
601 * Return:
602 * 0: success
603 * errno: fail
604 */
ipc_hunt_by_name(const char * name,uint32_t * task_id)605 uint32_t ipc_hunt_by_name(const char *name, uint32_t *task_id)
606 {
607 int ret;
608
609 ret = __ipc_util_hunt_by_name(name, task_id);
610
611 return ret;
612 }
613
614 /*
615 * Get the ch_numth channel cap stored in pthread struct.
616 * @ch_num: the ch_numth channel in pthread struct
617 * @p_ch: output the ch_numth channel cap in pthread struct
618 *
619 * Get the ch_numth channel cap from pthread struct.
620 * Return:
621 * 0: success
622 * errno: fail
623 */
ipc_get_my_channel(int32_t ch_num,cref_t * p_ch)624 int32_t ipc_get_my_channel(int32_t ch_num, cref_t *p_ch)
625 {
626 if (ch_num != 0 && ch_num != 1) {
627 return -EINVAL;
628 }
629 if (__ipc_tls.channel[ch_num] <= 0) {
630 return -ENOENT;
631 }
632 *p_ch = __ipc_tls.channel[ch_num];
633 return 0;
634 }
635
636 /*
637 * ipc_msg_call to the given channel, waiting for server's ipc_reply.
638 * @channel: cap of the channel
639 * @send_buf: send message buffer to be transfered to the server
640 * @send_len: length of the send buffer
641 * @reply_buf: reply buffer to be filled in when ipc_msg_reply from the server
642 * @reply_len: length of reply buffer
643 * @timeout: timeout
644 *
645 * ipc_msg_call will block current thread temporarily and transfer msg @send_buf
646 * to server. Current thread will be resumed after the server calls
647 * ipc_msg_reply.
648 * Return:
649 * 0: success
650 * errno: fail
651 */
ipc_msg_call(cref_t channel,void * send_buf,size_t send_len,void * reply_buf,size_t reply_len,int32_t timeout)652 int32_t ipc_msg_call(cref_t channel, void *send_buf, size_t send_len,
653 void *reply_buf, size_t reply_len, int32_t timeout)
654 {
655 int ret;
656
657 ret = usys_tee_msg_call(
658 channel, send_buf, send_len, reply_buf, reply_len, NULL);
659
660 return ret;
661 }
662
663 /*
664 * ipc_msg_reply to the given msg_hdl.
665 * @msg_hdl: cap of the msg_hdl
666 * @reply_buf: message buffer to be transfered back to client
667 * @len: length of reply buffer
668 * @timeout: timeout
669 *
670 * The client to be replied, which is recored in msg_hdl, will be resumed after
671 * ipc_msg_reply.
672 * Return:
673 * 0: success
674 * errno: fail
675 */
ipc_msg_reply(cref_t msg_hdl,void * reply_buf,size_t len)676 int32_t ipc_msg_reply(cref_t msg_hdl, void *reply_buf, size_t len)
677 {
678 int ret;
679
680 ret = usys_tee_msg_reply(msg_hdl, reply_buf, len);
681
682 return ret;
683 }
684
685 /*
686 * ipc_msg_notification to the given channel.
687 * @ch: cap of the channel
688 * @send_buf: message buffer to be transfered to the server
689 * @send_len: length of the send buffer
690 *
691 * ipc_msg_notification sends message asynchronously to the given channel, which
692 * will not block current thread at all.
693 * Return:
694 * 0: success
695 * errno: fail
696 */
ipc_msg_notification(cref_t ch,void * send_buf,size_t send_len)697 int32_t ipc_msg_notification(cref_t ch, void *send_buf, size_t send_len)
698 {
699 int ret;
700
701 ret = usys_tee_msg_notify(ch, send_buf, send_len);
702
703 return ret;
704 }
705
706 /*
707 * ipc_msg_receive at the given channel.
708 * @channel: cap of the channel
709 * @recv_buf: the buffer to be filled in with client's message
710 * @recv_len: length of the recv buffer
711 * @msg_hdl: cap of the msg_hdl
712 * @info: the info(client's taskid, message type(sync or async)) of the ipc
713 * @timeout: timeout
714 *
715 * Current server thread will wait for message.
716 * Return:
717 * 0: success
718 * errno: fail
719 */
ipc_msg_receive(cref_t channel,void * recv_buf,size_t recv_len,cref_t msg_hdl,struct src_msginfo * info,int32_t timeout)720 int32_t ipc_msg_receive(cref_t channel, void *recv_buf, size_t recv_len,
721 cref_t msg_hdl, struct src_msginfo *info,
722 int32_t timeout)
723 {
724 int ret;
725
726 ret = usys_tee_msg_receive(
727 channel, recv_buf, recv_len, msg_hdl, info, timeout);
728
729 return ret;
730 }
731
732 /*
733 * Create msg_hdl.
734 *
735 * Create msg_hdl and return cap of the msg_hdl.
736 * Return:
737 * >= 0: cap of the msg_hdl
738 * errno: fail
739 */
ipc_msg_create_hdl(void)740 cref_t ipc_msg_create_hdl(void)
741 {
742 int ret;
743
744 ret = usys_tee_msg_create_msg_hdl();
745
746 return ret;
747 }
748
749 /*
750 * Delete msg_hdl.
751 * @msg_hdl: cap of the msg_hdl
752 *
753 * Revoke msg_hdl cap directly.
754 * Return:
755 * 0: success
756 * errno: fail
757 */
ipc_msg_delete_hdl(cref_t msg_hdl)758 int32_t ipc_msg_delete_hdl(cref_t msg_hdl)
759 {
760 int ret;
761
762 ret = usys_revoke_cap(msg_hdl, false);
763
764 return ret;
765 }
766
767 /*
768 * Save msg_hdl locally.
769 * @msg_hdl: cap of the msg_hdl
770 *
771 * Save msg_hdl cap into pthread struct.
772 */
ipc_save_my_msghdl(cref_t msg_hdl)773 int32_t ipc_save_my_msghdl(cref_t msg_hdl)
774 {
775 __ipc_tls.msg_hdl = msg_hdl;
776 return 0;
777 }
778
779 /*
780 * Get msg_hdl locally.
781 *
782 * Return msg_hdl cap stored in pthread struct.
783 * Return:
784 * >= 0: cap of the msg_hdl
785 * errno: fail
786 */
ipc_get_my_msghdl(void)787 cref_t ipc_get_my_msghdl(void)
788 {
789 if (__ipc_tls.msg_hdl == 0) {
790 __ipc_tls.msg_hdl = ipc_msg_create_hdl();
791 }
792 return __ipc_tls.msg_hdl;
793 }
794
795 /*
796 * Get taskid of current thread.
797 *
798 * Return taskid of current thread.
799 * Return: taskid
800 */
get_self_taskid(void)801 uint32_t get_self_taskid(void)
802 {
803 return pid_to_taskid(gettid(), getpid());
804 }
805
check_ref_valid(cref_t cref)806 bool check_ref_valid(cref_t cref)
807 {
808 return cref >= 0;
809 }
810
tamgr_register(const char * name)811 int tamgr_register(const char *name)
812 {
813 return __ipc_util_register_tamgr(name);
814 }
815