1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  * Copyright (c) 2020, Linaro Limited
5  */
6 
7 #include <kernel/panic.h>
8 #include <kernel/pseudo_ta.h>
9 #include <kernel/tee_ta_manager.h>
10 #include <kernel/thread.h>
11 #include <kernel/ts_manager.h>
12 #include <kernel/user_mode_ctx.h>
13 #include <mm/core_mmu.h>
14 #include <mm/vm.h>
15 
update_current_ctx(struct thread_specific_data * tsd)16 static void update_current_ctx(struct thread_specific_data *tsd)
17 {
18 	struct ts_ctx *ctx = NULL;
19 	struct ts_session *s = TAILQ_FIRST(&tsd->sess_stack);
20 
21 	if (s) {
22 		if (is_pseudo_ta_ctx(s->ctx))
23 			s = TAILQ_NEXT(s, link_tsd);
24 
25 		if (s)
26 			ctx = s->ctx;
27 	}
28 
29 	if (tsd->ctx != ctx)
30 		vm_set_ctx(ctx);
31 	/*
32 	 * If current context is of user mode, then it has to be active too.
33 	 */
34 	if (is_user_mode_ctx(ctx) != core_mmu_user_mapping_is_active())
35 		panic("unexpected active mapping");
36 }
37 
ts_push_current_session(struct ts_session * s)38 void ts_push_current_session(struct ts_session *s)
39 {
40 	struct thread_specific_data *tsd = thread_get_tsd();
41 
42 	TAILQ_INSERT_HEAD(&tsd->sess_stack, s, link_tsd);
43 	update_current_ctx(tsd);
44 }
45 
ts_pop_current_session(void)46 struct ts_session *ts_pop_current_session(void)
47 {
48 	struct thread_specific_data *tsd = thread_get_tsd();
49 	struct ts_session *s = TAILQ_FIRST(&tsd->sess_stack);
50 
51 	if (s) {
52 		TAILQ_REMOVE(&tsd->sess_stack, s, link_tsd);
53 		update_current_ctx(tsd);
54 	}
55 	return s;
56 }
57 
ts_get_calling_session(void)58 struct ts_session *ts_get_calling_session(void)
59 {
60 	struct ts_session *s = ts_get_current_session();
61 
62 	if (s)
63 		s = TAILQ_NEXT(s, link_tsd);
64 	return s;
65 }
66 
ts_get_current_session_may_fail(void)67 struct ts_session *ts_get_current_session_may_fail(void)
68 {
69 	return TAILQ_FIRST(&thread_get_tsd()->sess_stack);
70 }
71 
ts_get_current_session(void)72 struct ts_session *ts_get_current_session(void)
73 {
74 	struct ts_session *s = ts_get_current_session_may_fail();
75 
76 	if (!s)
77 		panic();
78 	return s;
79 }
80