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