xref: /optee_os/core/kernel/ts_manager.c (revision 4440385e8ba07630bf20898ba9c32d67d9974dbd)
100b3b9a2SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
200b3b9a2SJens Wiklander /*
300b3b9a2SJens Wiklander  * Copyright (c) 2014, STMicroelectronics International N.V.
400b3b9a2SJens Wiklander  * Copyright (c) 2020, Linaro Limited
500b3b9a2SJens Wiklander  */
600b3b9a2SJens Wiklander 
700b3b9a2SJens Wiklander #include <kernel/panic.h>
800b3b9a2SJens Wiklander #include <kernel/pseudo_ta.h>
900b3b9a2SJens Wiklander #include <kernel/tee_ta_manager.h>
1000b3b9a2SJens Wiklander #include <kernel/thread.h>
1189c9728dSJens Wiklander #include <kernel/ts_manager.h>
1200b3b9a2SJens Wiklander #include <kernel/user_mode_ctx.h>
1300b3b9a2SJens Wiklander #include <mm/core_mmu.h>
1489c9728dSJens Wiklander #include <mm/vm.h>
1500b3b9a2SJens Wiklander 
update_current_ctx(struct thread_specific_data * tsd)1600b3b9a2SJens Wiklander static void update_current_ctx(struct thread_specific_data *tsd)
1700b3b9a2SJens Wiklander {
183560d990SJens Wiklander 	struct ts_ctx *ctx = NULL;
1900b3b9a2SJens Wiklander 	struct ts_session *s = TAILQ_FIRST(&tsd->sess_stack);
2000b3b9a2SJens Wiklander 
2100b3b9a2SJens Wiklander 	if (s) {
2200b3b9a2SJens Wiklander 		if (is_pseudo_ta_ctx(s->ctx))
2300b3b9a2SJens Wiklander 			s = TAILQ_NEXT(s, link_tsd);
2400b3b9a2SJens Wiklander 
2500b3b9a2SJens Wiklander 		if (s)
2600b3b9a2SJens Wiklander 			ctx = s->ctx;
2700b3b9a2SJens Wiklander 	}
2800b3b9a2SJens Wiklander 
2900b3b9a2SJens Wiklander 	if (tsd->ctx != ctx)
3089c9728dSJens Wiklander 		vm_set_ctx(ctx);
3100b3b9a2SJens Wiklander 	/*
3200b3b9a2SJens Wiklander 	 * If current context is of user mode, then it has to be active too.
3300b3b9a2SJens Wiklander 	 */
3400b3b9a2SJens Wiklander 	if (is_user_mode_ctx(ctx) != core_mmu_user_mapping_is_active())
3500b3b9a2SJens Wiklander 		panic("unexpected active mapping");
3600b3b9a2SJens Wiklander }
3700b3b9a2SJens Wiklander 
ts_push_current_session(struct ts_session * s)3800b3b9a2SJens Wiklander void ts_push_current_session(struct ts_session *s)
3900b3b9a2SJens Wiklander {
4000b3b9a2SJens Wiklander 	struct thread_specific_data *tsd = thread_get_tsd();
4100b3b9a2SJens Wiklander 
4200b3b9a2SJens Wiklander 	TAILQ_INSERT_HEAD(&tsd->sess_stack, s, link_tsd);
4300b3b9a2SJens Wiklander 	update_current_ctx(tsd);
4400b3b9a2SJens Wiklander }
4500b3b9a2SJens Wiklander 
ts_pop_current_session(void)4600b3b9a2SJens Wiklander struct ts_session *ts_pop_current_session(void)
4700b3b9a2SJens Wiklander {
4800b3b9a2SJens Wiklander 	struct thread_specific_data *tsd = thread_get_tsd();
4900b3b9a2SJens Wiklander 	struct ts_session *s = TAILQ_FIRST(&tsd->sess_stack);
5000b3b9a2SJens Wiklander 
5100b3b9a2SJens Wiklander 	if (s) {
5200b3b9a2SJens Wiklander 		TAILQ_REMOVE(&tsd->sess_stack, s, link_tsd);
5300b3b9a2SJens Wiklander 		update_current_ctx(tsd);
5400b3b9a2SJens Wiklander 	}
5500b3b9a2SJens Wiklander 	return s;
5600b3b9a2SJens Wiklander }
5700b3b9a2SJens Wiklander 
ts_get_calling_session(void)5800b3b9a2SJens Wiklander struct ts_session *ts_get_calling_session(void)
5900b3b9a2SJens Wiklander {
60*4440385eSJorge Ramirez-Ortiz 	return TAILQ_NEXT(ts_get_current_session(), link_tsd);
6100b3b9a2SJens Wiklander }
6200b3b9a2SJens Wiklander 
ts_get_current_session_may_fail(void)6300b3b9a2SJens Wiklander struct ts_session *ts_get_current_session_may_fail(void)
6400b3b9a2SJens Wiklander {
6500b3b9a2SJens Wiklander 	return TAILQ_FIRST(&thread_get_tsd()->sess_stack);
6600b3b9a2SJens Wiklander }
6700b3b9a2SJens Wiklander 
ts_get_current_session(void)6800b3b9a2SJens Wiklander struct ts_session *ts_get_current_session(void)
6900b3b9a2SJens Wiklander {
7000b3b9a2SJens Wiklander 	struct ts_session *s = ts_get_current_session_may_fail();
7100b3b9a2SJens Wiklander 
7200b3b9a2SJens Wiklander 	if (!s)
7300b3b9a2SJens Wiklander 		panic();
7400b3b9a2SJens Wiklander 	return s;
7500b3b9a2SJens Wiklander }
76