xref: /optee_os/core/kernel/ts_manager.c (revision 89c9728d981ff0f4a8edecc325858537441d721e)
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>
11*89c9728dSJens Wiklander #include <kernel/ts_manager.h>
1200b3b9a2SJens Wiklander #include <kernel/user_mode_ctx.h>
1300b3b9a2SJens Wiklander #include <mm/core_mmu.h>
14*89c9728dSJens Wiklander #include <mm/vm.h>
1500b3b9a2SJens Wiklander 
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)
30*89c9728dSJens 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 
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 
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 
5800b3b9a2SJens Wiklander struct ts_session *ts_get_calling_session(void)
5900b3b9a2SJens Wiklander {
6000b3b9a2SJens Wiklander 	struct ts_session *s = ts_get_current_session();
6100b3b9a2SJens Wiklander 
6200b3b9a2SJens Wiklander 	if (s)
6300b3b9a2SJens Wiklander 		s = TAILQ_NEXT(s, link_tsd);
6400b3b9a2SJens Wiklander 	return s;
6500b3b9a2SJens Wiklander }
6600b3b9a2SJens Wiklander 
6700b3b9a2SJens Wiklander struct ts_session *ts_get_current_session_may_fail(void)
6800b3b9a2SJens Wiklander {
6900b3b9a2SJens Wiklander 	return TAILQ_FIRST(&thread_get_tsd()->sess_stack);
7000b3b9a2SJens Wiklander }
7100b3b9a2SJens Wiklander 
7200b3b9a2SJens Wiklander struct ts_session *ts_get_current_session(void)
7300b3b9a2SJens Wiklander {
7400b3b9a2SJens Wiklander 	struct ts_session *s = ts_get_current_session_may_fail();
7500b3b9a2SJens Wiklander 
7600b3b9a2SJens Wiklander 	if (!s)
7700b3b9a2SJens Wiklander 		panic();
7800b3b9a2SJens Wiklander 	return s;
7900b3b9a2SJens Wiklander }
80