xref: /optee_os/core/arch/arm/kernel/thread.c (revision 9bdc34f232fcac3c42210f9ae8fa0c54fc44ddb2)
1 /*
2  * Copyright (c) 2014, STMicroelectronics International N.V.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 #include <platform_config.h>
28 #include <kernel/panic.h>
29 #include <kernel/thread.h>
30 #include <kernel/thread_defs.h>
31 #include "thread_private.h"
32 #include <sm/sm_defs.h>
33 #include <sm/sm.h>
34 #include <sm/teesmc.h>
35 #include <sm/teesmc_optee.h>
36 #include <arm.h>
37 #include <kernel/tz_proc_def.h>
38 #include <kernel/tz_proc.h>
39 #include <kernel/misc.h>
40 #include <mm/tee_mmu.h>
41 #include <mm/tee_mmu_defs.h>
42 #include <mm/tee_mm.h>
43 #include <mm/tee_pager.h>
44 #include <kernel/tee_ta_manager.h>
45 #include <util.h>
46 #include <trace.h>
47 #include <assert.h>
48 
49 #ifdef ARM32
50 #define STACK_TMP_SIZE		1024
51 #define STACK_THREAD_SIZE	8192
52 
53 #if TRACE_LEVEL > 0
54 #define STACK_ABT_SIZE		2048
55 #else
56 #define STACK_ABT_SIZE		1024
57 #endif
58 
59 #endif /*ARM32*/
60 
61 #ifdef ARM64
62 #define STACK_TMP_SIZE		2048
63 #define STACK_THREAD_SIZE	8192
64 
65 #if TRACE_LEVEL > 0
66 #define STACK_ABT_SIZE		3072
67 #else
68 #define STACK_ABT_SIZE		1024
69 #endif
70 #endif /*ARM64*/
71 
72 #define RPC_MAX_PARAMS		2
73 
74 /*
75  * The big lock for threads. Since OP-TEE currently is single threaded
76  * all standard calls (non-fast calls) must take this mutex before starting
77  * to do any real work.
78  */
79 static struct mutex thread_big_lock = MUTEX_INITIALIZER;
80 
81 struct thread_ctx threads[CFG_NUM_THREADS];
82 
83 static struct thread_core_local thread_core_local[CFG_TEE_CORE_NB_CORE];
84 
85 #ifdef CFG_WITH_VFP
86 struct thread_vfp_state {
87 	bool ns_saved;
88 	bool sec_saved;
89 	bool sec_lazy_saved;
90 	struct vfp_state ns;
91 	struct vfp_state sec;
92 };
93 
94 static struct thread_vfp_state thread_vfp_state;
95 #endif /*CFG_WITH_VFP*/
96 
97 #ifdef CFG_WITH_STACK_CANARIES
98 #ifdef ARM32
99 #define STACK_CANARY_SIZE	(4 * sizeof(uint32_t))
100 #endif
101 #ifdef ARM64
102 #define STACK_CANARY_SIZE	(8 * sizeof(uint32_t))
103 #endif
104 #define START_CANARY_VALUE	0xdededede
105 #define END_CANARY_VALUE	0xabababab
106 #define GET_START_CANARY(name, stack_num) name[stack_num][0]
107 #define GET_END_CANARY(name, stack_num) \
108 	name[stack_num][sizeof(name[stack_num]) / sizeof(uint32_t) - 1]
109 #else
110 #define STACK_CANARY_SIZE	0
111 #endif
112 
113 #define DECLARE_STACK(name, num_stacks, stack_size) \
114 	static uint32_t name[num_stacks][ \
115 		ROUNDUP(stack_size + STACK_CANARY_SIZE, STACK_ALIGNMENT) / \
116 		sizeof(uint32_t)] \
117 		__attribute__((section(".nozi.stack"), \
118 			       aligned(STACK_ALIGNMENT)))
119 
120 #define GET_STACK(stack) \
121 	((vaddr_t)(stack) + sizeof(stack) - STACK_CANARY_SIZE / 2)
122 
123 DECLARE_STACK(stack_tmp,	CFG_TEE_CORE_NB_CORE,	STACK_TMP_SIZE);
124 DECLARE_STACK(stack_abt,	CFG_TEE_CORE_NB_CORE,	STACK_ABT_SIZE);
125 #if !defined(CFG_WITH_ARM_TRUSTED_FW)
126 DECLARE_STACK(stack_sm,		CFG_TEE_CORE_NB_CORE,	SM_STACK_SIZE);
127 #endif
128 #ifndef CFG_WITH_PAGER
129 DECLARE_STACK(stack_thread,	CFG_NUM_THREADS,	STACK_THREAD_SIZE);
130 #endif
131 
132 const vaddr_t stack_tmp_top[CFG_TEE_CORE_NB_CORE] = {
133 	GET_STACK(stack_tmp[0]),
134 #if CFG_TEE_CORE_NB_CORE > 1
135 	GET_STACK(stack_tmp[1]),
136 #endif
137 #if CFG_TEE_CORE_NB_CORE > 2
138 	GET_STACK(stack_tmp[2]),
139 #endif
140 #if CFG_TEE_CORE_NB_CORE > 3
141 	GET_STACK(stack_tmp[3]),
142 #endif
143 #if CFG_TEE_CORE_NB_CORE > 4
144 	GET_STACK(stack_tmp[4]),
145 #endif
146 #if CFG_TEE_CORE_NB_CORE > 5
147 	GET_STACK(stack_tmp[5]),
148 #endif
149 #if CFG_TEE_CORE_NB_CORE > 6
150 	GET_STACK(stack_tmp[6]),
151 #endif
152 #if CFG_TEE_CORE_NB_CORE > 7
153 	GET_STACK(stack_tmp[7]),
154 #endif
155 #if CFG_TEE_CORE_NB_CORE > 8
156 #error "Top of tmp stacks aren't defined for more than 8 CPUS"
157 #endif
158 };
159 
160 thread_smc_handler_t thread_std_smc_handler_ptr;
161 static thread_smc_handler_t thread_fast_smc_handler_ptr;
162 thread_fiq_handler_t thread_fiq_handler_ptr;
163 thread_svc_handler_t thread_svc_handler_ptr;
164 static thread_abort_handler_t thread_abort_handler_ptr;
165 thread_pm_handler_t thread_cpu_on_handler_ptr;
166 thread_pm_handler_t thread_cpu_off_handler_ptr;
167 thread_pm_handler_t thread_cpu_suspend_handler_ptr;
168 thread_pm_handler_t thread_cpu_resume_handler_ptr;
169 thread_pm_handler_t thread_system_off_handler_ptr;
170 thread_pm_handler_t thread_system_reset_handler_ptr;
171 
172 
173 static unsigned int thread_global_lock = SPINLOCK_UNLOCK;
174 
175 static void init_canaries(void)
176 {
177 #ifdef CFG_WITH_STACK_CANARIES
178 	size_t n;
179 #define INIT_CANARY(name)						\
180 	for (n = 0; n < ARRAY_SIZE(name); n++) {			\
181 		uint32_t *start_canary = &GET_START_CANARY(name, n);	\
182 		uint32_t *end_canary = &GET_END_CANARY(name, n);	\
183 									\
184 		*start_canary = START_CANARY_VALUE;			\
185 		*end_canary = END_CANARY_VALUE;				\
186 		DMSG("#Stack canaries for %s[%zu] with top at %p\n",	\
187 			#name, n, (void *)(end_canary - 1));		\
188 		DMSG("watch *%p\n", (void *)end_canary);		\
189 	}
190 
191 	INIT_CANARY(stack_tmp);
192 	INIT_CANARY(stack_abt);
193 #if !defined(CFG_WITH_ARM_TRUSTED_FW)
194 	INIT_CANARY(stack_sm);
195 #endif
196 #ifndef CFG_WITH_PAGER
197 	INIT_CANARY(stack_thread);
198 #endif
199 #endif/*CFG_WITH_STACK_CANARIES*/
200 }
201 
202 void thread_check_canaries(void)
203 {
204 #ifdef CFG_WITH_STACK_CANARIES
205 	size_t n;
206 
207 	for (n = 0; n < ARRAY_SIZE(stack_tmp); n++) {
208 		assert(GET_START_CANARY(stack_tmp, n) == START_CANARY_VALUE);
209 		assert(GET_END_CANARY(stack_tmp, n) == END_CANARY_VALUE);
210 	}
211 
212 	for (n = 0; n < ARRAY_SIZE(stack_abt); n++) {
213 		assert(GET_START_CANARY(stack_abt, n) == START_CANARY_VALUE);
214 		assert(GET_END_CANARY(stack_abt, n) == END_CANARY_VALUE);
215 	}
216 #if !defined(CFG_WITH_ARM_TRUSTED_FW)
217 	for (n = 0; n < ARRAY_SIZE(stack_sm); n++) {
218 		assert(GET_START_CANARY(stack_sm, n) == START_CANARY_VALUE);
219 		assert(GET_END_CANARY(stack_sm, n) == END_CANARY_VALUE);
220 	}
221 #endif
222 #ifndef CFG_WITH_PAGER
223 	for (n = 0; n < ARRAY_SIZE(stack_thread); n++) {
224 		assert(GET_START_CANARY(stack_thread, n) == START_CANARY_VALUE);
225 		assert(GET_END_CANARY(stack_thread, n) == END_CANARY_VALUE);
226 	}
227 #endif
228 #endif/*CFG_WITH_STACK_CANARIES*/
229 }
230 
231 static void lock_global(void)
232 {
233 	cpu_spin_lock(&thread_global_lock);
234 }
235 
236 static void unlock_global(void)
237 {
238 	cpu_spin_unlock(&thread_global_lock);
239 }
240 
241 #ifdef ARM32
242 uint32_t thread_get_exceptions(void)
243 {
244 	uint32_t cpsr = read_cpsr();
245 
246 	return (cpsr >> CPSR_F_SHIFT) & THREAD_EXCP_ALL;
247 }
248 
249 void thread_set_exceptions(uint32_t exceptions)
250 {
251 	uint32_t cpsr = read_cpsr();
252 
253 	cpsr &= ~(THREAD_EXCP_ALL << CPSR_F_SHIFT);
254 	cpsr |= ((exceptions & THREAD_EXCP_ALL) << CPSR_F_SHIFT);
255 	write_cpsr(cpsr);
256 }
257 #endif /*ARM32*/
258 
259 #ifdef ARM64
260 uint32_t thread_get_exceptions(void)
261 {
262 	uint32_t daif = read_daif();
263 
264 	return (daif >> DAIF_F_SHIFT) & THREAD_EXCP_ALL;
265 }
266 
267 void thread_set_exceptions(uint32_t exceptions)
268 {
269 	uint32_t daif = read_daif();
270 
271 	daif &= ~(THREAD_EXCP_ALL << DAIF_F_SHIFT);
272 	daif |= ((exceptions & THREAD_EXCP_ALL) << DAIF_F_SHIFT);
273 	write_daif(daif);
274 }
275 #endif /*ARM64*/
276 
277 uint32_t thread_mask_exceptions(uint32_t exceptions)
278 {
279 	uint32_t state = thread_get_exceptions();
280 
281 	thread_set_exceptions(state | (exceptions & THREAD_EXCP_ALL));
282 	return state;
283 }
284 
285 void thread_unmask_exceptions(uint32_t state)
286 {
287 	thread_set_exceptions(state & THREAD_EXCP_ALL);
288 }
289 
290 
291 struct thread_core_local *thread_get_core_local(void)
292 {
293 	uint32_t cpu_id = get_core_pos();
294 
295 	/*
296 	 * IRQs must be disabled before playing with core_local since
297 	 * we otherwise may be rescheduled to a different core in the
298 	 * middle of this function.
299 	 */
300 	assert(thread_get_exceptions() & THREAD_EXCP_IRQ);
301 
302 	assert(cpu_id < CFG_TEE_CORE_NB_CORE);
303 	return &thread_core_local[cpu_id];
304 }
305 
306 static void thread_lazy_save_ns_vfp(void)
307 {
308 #ifdef CFG_WITH_VFP
309 	thread_vfp_state.ns_saved = false;
310 #if defined(ARM64) && defined(CFG_WITH_ARM_TRUSTED_FW)
311 	/*
312 	 * ARM TF saves and restores CPACR_EL1, so we must assume NS world
313 	 * uses VFP and always preserve the register file when secure world
314 	 * is about to use it
315 	 */
316 	thread_vfp_state.ns.force_save = true;
317 #endif
318 	vfp_lazy_save_state_init(&thread_vfp_state.ns);
319 #endif /*CFG_WITH_VFP*/
320 }
321 
322 static void thread_lazy_restore_ns_vfp(void)
323 {
324 #ifdef CFG_WITH_VFP
325 	assert(!thread_vfp_state.sec_lazy_saved && !thread_vfp_state.sec_saved);
326 	vfp_lazy_restore_state(&thread_vfp_state.ns, thread_vfp_state.ns_saved);
327 	thread_vfp_state.ns_saved = false;
328 #endif /*CFG_WITH_VFP*/
329 }
330 
331 #ifdef ARM32
332 static void init_regs(struct thread_ctx *thread,
333 		struct thread_smc_args *args)
334 {
335 	thread->regs.pc = (uint32_t)thread_std_smc_entry;
336 
337 	/*
338 	 * Stdcalls starts in SVC mode with masked IRQ, masked Asynchronous
339 	 * abort and unmasked FIQ.
340 	  */
341 	thread->regs.cpsr = read_cpsr() & ARM32_CPSR_E;
342 	thread->regs.cpsr |= CPSR_MODE_SVC | CPSR_I | CPSR_A;
343 	/* Enable thumb mode if it's a thumb instruction */
344 	if (thread->regs.pc & 1)
345 		thread->regs.cpsr |= CPSR_T;
346 	/* Reinitialize stack pointer */
347 	thread->regs.svc_sp = thread->stack_va_end;
348 
349 	/*
350 	 * Copy arguments into context. This will make the
351 	 * arguments appear in r0-r7 when thread is started.
352 	 */
353 	thread->regs.r0 = args->a0;
354 	thread->regs.r1 = args->a1;
355 	thread->regs.r2 = args->a2;
356 	thread->regs.r3 = args->a3;
357 	thread->regs.r4 = args->a4;
358 	thread->regs.r5 = args->a5;
359 	thread->regs.r6 = args->a6;
360 	thread->regs.r7 = args->a7;
361 }
362 #endif /*ARM32*/
363 
364 #ifdef ARM64
365 static void init_regs(struct thread_ctx *thread,
366 		struct thread_smc_args *args)
367 {
368 	thread->regs.pc = (uint64_t)thread_std_smc_entry;
369 
370 	/*
371 	 * Stdcalls starts in SVC mode with masked IRQ, masked Asynchronous
372 	 * abort and unmasked FIQ.
373 	  */
374 	thread->regs.cpsr = SPSR_64(SPSR_64_MODE_EL1, SPSR_64_MODE_SP_EL0,
375 				    DAIFBIT_IRQ | DAIFBIT_ABT);
376 	/* Reinitialize stack pointer */
377 	thread->regs.sp = thread->stack_va_end;
378 
379 	/*
380 	 * Copy arguments into context. This will make the
381 	 * arguments appear in x0-x7 when thread is started.
382 	 */
383 	thread->regs.x[0] = args->a0;
384 	thread->regs.x[1] = args->a1;
385 	thread->regs.x[2] = args->a2;
386 	thread->regs.x[3] = args->a3;
387 	thread->regs.x[4] = args->a4;
388 	thread->regs.x[5] = args->a5;
389 	thread->regs.x[6] = args->a6;
390 	thread->regs.x[7] = args->a7;
391 }
392 #endif /*ARM64*/
393 
394 static void thread_alloc_and_run(struct thread_smc_args *args)
395 {
396 	size_t n;
397 	struct thread_core_local *l = thread_get_core_local();
398 	bool found_thread = false;
399 
400 	assert(l->curr_thread == -1);
401 
402 	lock_global();
403 
404 	for (n = 0; n < CFG_NUM_THREADS; n++) {
405 		if (threads[n].state == THREAD_STATE_FREE) {
406 			threads[n].state = THREAD_STATE_ACTIVE;
407 			found_thread = true;
408 			break;
409 		}
410 	}
411 
412 	unlock_global();
413 
414 	if (!found_thread) {
415 		args->a0 = TEESMC_RETURN_ETHREAD_LIMIT;
416 		return;
417 	}
418 
419 	l->curr_thread = n;
420 
421 	threads[n].flags = 0;
422 	init_regs(threads + n, args);
423 
424 	/* Save Hypervisor Client ID */
425 	threads[n].hyp_clnt_id = args->a7;
426 
427 	thread_lazy_save_ns_vfp();
428 	thread_resume(&threads[n].regs);
429 }
430 
431 #ifdef ARM32
432 static void copy_a0_to_a3(struct thread_ctx_regs *regs,
433 		struct thread_smc_args *args)
434 {
435 	/*
436 	 * Update returned values from RPC, values will appear in
437 	 * r0-r3 when thread is resumed.
438 	 */
439 	regs->r0 = args->a0;
440 	regs->r1 = args->a1;
441 	regs->r2 = args->a2;
442 	regs->r3 = args->a3;
443 }
444 #endif /*ARM32*/
445 
446 #ifdef ARM64
447 static void copy_a0_to_a3(struct thread_ctx_regs *regs,
448 		struct thread_smc_args *args)
449 {
450 	/*
451 	 * Update returned values from RPC, values will appear in
452 	 * x0-x3 when thread is resumed.
453 	 */
454 	regs->x[0] = args->a0;
455 	regs->x[1] = args->a1;
456 	regs->x[2] = args->a2;
457 	regs->x[3] = args->a3;
458 }
459 #endif /*ARM64*/
460 
461 static void thread_resume_from_rpc(struct thread_smc_args *args)
462 {
463 	size_t n = args->a3; /* thread id */
464 	struct thread_core_local *l = thread_get_core_local();
465 	uint32_t rv = 0;
466 
467 	assert(l->curr_thread == -1);
468 
469 	lock_global();
470 
471 	if (n < CFG_NUM_THREADS &&
472 	    threads[n].state == THREAD_STATE_SUSPENDED &&
473 	    args->a7 == threads[n].hyp_clnt_id)
474 		threads[n].state = THREAD_STATE_ACTIVE;
475 	else
476 		rv = TEESMC_RETURN_ERESUME;
477 
478 	unlock_global();
479 
480 	if (rv) {
481 		args->a0 = rv;
482 		return;
483 	}
484 
485 	l->curr_thread = n;
486 
487 	if (threads[n].have_user_map)
488 		core_mmu_set_user_map(&threads[n].user_map);
489 
490 	/*
491 	 * Return from RPC to request service of an IRQ must not
492 	 * get parameters from non-secure world.
493 	 */
494 	if (threads[n].flags & THREAD_FLAGS_COPY_ARGS_ON_RETURN) {
495 		copy_a0_to_a3(&threads[n].regs, args);
496 		threads[n].flags &= ~THREAD_FLAGS_COPY_ARGS_ON_RETURN;
497 	}
498 
499 	thread_lazy_save_ns_vfp();
500 	thread_resume(&threads[n].regs);
501 }
502 
503 void thread_handle_fast_smc(struct thread_smc_args *args)
504 {
505 	thread_check_canaries();
506 	thread_fast_smc_handler_ptr(args);
507 	/* Fast handlers must not unmask any exceptions */
508 	assert(thread_get_exceptions() == THREAD_EXCP_ALL);
509 }
510 
511 void thread_handle_std_smc(struct thread_smc_args *args)
512 {
513 	thread_check_canaries();
514 
515 	if (args->a0 == TEESMC32_CALL_RETURN_FROM_RPC)
516 		thread_resume_from_rpc(args);
517 	else
518 		thread_alloc_and_run(args);
519 }
520 
521 /* Helper routine for the assembly function thread_std_smc_entry() */
522 void __thread_std_smc_entry(struct thread_smc_args *args)
523 {
524 	struct thread_ctx *thr = threads + thread_get_id();
525 
526 	if (!thr->rpc_arg) {
527 		paddr_t parg;
528 		void *arg;
529 
530 		parg = thread_rpc_alloc_arg(
531 				TEESMC32_GET_ARG_SIZE(RPC_MAX_PARAMS));
532 		if (!parg || !TEE_ALIGNMENT_IS_OK(parg, struct teesmc32_arg) ||
533 		     core_pa2va(parg, &arg)) {
534 			thread_rpc_free_arg(parg);
535 			args->a0 = TEESMC_RETURN_ENOMEM;
536 			return;
537 		}
538 
539 		thr->rpc_arg = arg;
540 		thr->rpc_parg = parg;
541 	}
542 
543 	/*
544 	 * Take big lock before entering the callback registered in
545 	 * thread_std_smc_handler_ptr as the callback can reside in the
546 	 * paged area and the pager can only serve one core at a time.
547 	 */
548 	thread_take_big_lock();
549 	thread_std_smc_handler_ptr(args);
550 	thread_release_big_lock();
551 }
552 
553 void thread_handle_abort(uint32_t abort_type, struct thread_abort_regs *regs)
554 {
555 #ifdef CFG_WITH_VFP
556 	if (vfp_is_enabled()) {
557 		vfp_lazy_save_state_init(&thread_vfp_state.sec);
558 		thread_vfp_state.sec_lazy_saved = true;
559 	}
560 #endif
561 
562 	thread_abort_handler_ptr(abort_type, regs);
563 
564 #ifdef CFG_WITH_VFP
565 	assert(!vfp_is_enabled());
566 	if (thread_vfp_state.sec_lazy_saved) {
567 		vfp_lazy_restore_state(&thread_vfp_state.sec,
568 				       thread_vfp_state.sec_saved);
569 		thread_vfp_state.sec_saved = false;
570 		thread_vfp_state.sec_lazy_saved = false;
571 	}
572 #endif
573 }
574 
575 void *thread_get_tmp_sp(void)
576 {
577 	struct thread_core_local *l = thread_get_core_local();
578 
579 	return (void *)l->tmp_stack_va_end;
580 }
581 
582 #ifdef ARM64
583 vaddr_t thread_get_saved_thread_sp(void)
584 {
585 	struct thread_core_local *l = thread_get_core_local();
586 	int ct = l->curr_thread;
587 
588 	assert(ct != -1);
589 	return threads[ct].kern_sp;
590 }
591 #endif /*ARM64*/
592 
593 void thread_state_free(void)
594 {
595 	struct thread_core_local *l = thread_get_core_local();
596 	int ct = l->curr_thread;
597 
598 	assert(ct != -1);
599 
600 	thread_lazy_restore_ns_vfp();
601 
602 	lock_global();
603 
604 	assert(threads[ct].state == THREAD_STATE_ACTIVE);
605 	threads[ct].state = THREAD_STATE_FREE;
606 	threads[ct].flags = 0;
607 	l->curr_thread = -1;
608 
609 	unlock_global();
610 }
611 
612 int thread_state_suspend(uint32_t flags, uint32_t cpsr, vaddr_t pc)
613 {
614 	struct thread_core_local *l = thread_get_core_local();
615 	int ct = l->curr_thread;
616 
617 	assert(ct != -1);
618 
619 	thread_check_canaries();
620 
621 	thread_lazy_restore_ns_vfp();
622 
623 	lock_global();
624 
625 	assert(threads[ct].state == THREAD_STATE_ACTIVE);
626 	threads[ct].flags |= flags;
627 	threads[ct].regs.cpsr = cpsr;
628 	threads[ct].regs.pc = pc;
629 	threads[ct].state = THREAD_STATE_SUSPENDED;
630 
631 	threads[ct].have_user_map = core_mmu_user_mapping_is_active();
632 	if (threads[ct].have_user_map) {
633 		core_mmu_get_user_map(&threads[ct].user_map);
634 		core_mmu_set_user_map(NULL);
635 	}
636 
637 
638 	l->curr_thread = -1;
639 
640 	unlock_global();
641 
642 	return ct;
643 }
644 
645 #ifdef ARM32
646 static void set_tmp_stack(struct thread_core_local *l, vaddr_t sp)
647 {
648 	l->tmp_stack_va_end = sp;
649 	thread_set_irq_sp(sp);
650 	thread_set_fiq_sp(sp);
651 }
652 
653 static void set_abt_stack(struct thread_core_local *l __unused, vaddr_t sp)
654 {
655 	thread_set_abt_sp(sp);
656 }
657 #endif /*ARM32*/
658 
659 #ifdef ARM64
660 static void set_tmp_stack(struct thread_core_local *l, vaddr_t sp)
661 {
662 	/*
663 	 * We're already using the tmp stack when this function is called
664 	 * so there's no need to assign it to any stack pointer. However,
665 	 * we'll need to restore it at different times so store it here.
666 	 */
667 	l->tmp_stack_va_end = sp;
668 }
669 
670 static void set_abt_stack(struct thread_core_local *l, vaddr_t sp)
671 {
672 	l->abt_stack_va_end = sp;
673 }
674 #endif /*ARM64*/
675 
676 bool thread_init_stack(uint32_t thread_id, vaddr_t sp)
677 {
678 	if (thread_id >= CFG_NUM_THREADS)
679 		return false;
680 	if (threads[thread_id].state != THREAD_STATE_FREE)
681 		return false;
682 
683 	threads[thread_id].stack_va_end = sp;
684 	return true;
685 }
686 
687 int thread_get_id(void)
688 {
689 	/* thread_get_core_local() requires IRQs to be disabled */
690 	uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ);
691 	struct thread_core_local *l;
692 	int ct;
693 
694 	l = thread_get_core_local();
695 	ct = l->curr_thread;
696 	assert((ct >= 0) && (ct < CFG_NUM_THREADS));
697 
698 	thread_unmask_exceptions(exceptions);
699 	return ct;
700 }
701 
702 static void init_handlers(const struct thread_handlers *handlers)
703 {
704 	thread_std_smc_handler_ptr = handlers->std_smc;
705 	thread_fast_smc_handler_ptr = handlers->fast_smc;
706 	thread_fiq_handler_ptr = handlers->fiq;
707 	thread_svc_handler_ptr = handlers->svc;
708 	thread_abort_handler_ptr = handlers->abort;
709 	thread_cpu_on_handler_ptr = handlers->cpu_on;
710 	thread_cpu_off_handler_ptr = handlers->cpu_off;
711 	thread_cpu_suspend_handler_ptr = handlers->cpu_suspend;
712 	thread_cpu_resume_handler_ptr = handlers->cpu_resume;
713 	thread_system_off_handler_ptr = handlers->system_off;
714 	thread_system_reset_handler_ptr = handlers->system_reset;
715 }
716 
717 
718 #ifdef CFG_WITH_PAGER
719 static void init_thread_stacks(void)
720 {
721 	size_t n;
722 
723 	/*
724 	 * Allocate virtual memory for thread stacks.
725 	 */
726 	for (n = 0; n < CFG_NUM_THREADS; n++) {
727 		tee_mm_entry_t *mm;
728 		vaddr_t sp;
729 
730 		/* Find vmem for thread stack and its protection gap */
731 		mm = tee_mm_alloc(&tee_mm_vcore,
732 				  SMALL_PAGE_SIZE + STACK_THREAD_SIZE);
733 		TEE_ASSERT(mm);
734 
735 		/* Claim eventual physical page */
736 		tee_pager_add_pages(tee_mm_get_smem(mm), tee_mm_get_size(mm),
737 				    true);
738 
739 		/* Realloc both protection vmem and stack vmem separately */
740 		sp = tee_mm_get_smem(mm);
741 		tee_mm_free(mm);
742 		mm = tee_mm_alloc2(&tee_mm_vcore, sp, SMALL_PAGE_SIZE);
743 		TEE_ASSERT(mm);
744 		mm = tee_mm_alloc2(&tee_mm_vcore, sp + SMALL_PAGE_SIZE,
745 						  STACK_THREAD_SIZE);
746 		TEE_ASSERT(mm);
747 
748 		/* init effective stack */
749 		sp = tee_mm_get_smem(mm) + tee_mm_get_bytes(mm);
750 		if (!thread_init_stack(n, sp))
751 			panic();
752 
753 		/* Add the area to the pager */
754 		tee_pager_add_area(mm, TEE_PAGER_AREA_RW, NULL, NULL);
755 	}
756 }
757 #else
758 static void init_thread_stacks(void)
759 {
760 	size_t n;
761 
762 	/* Assign the thread stacks */
763 	for (n = 0; n < CFG_NUM_THREADS; n++) {
764 		if (!thread_init_stack(n, GET_STACK(stack_thread[n])))
765 			panic();
766 	}
767 }
768 #endif /*CFG_WITH_PAGER*/
769 
770 void thread_init_primary(const struct thread_handlers *handlers)
771 {
772 	size_t n;
773 
774 	/*
775 	 * The COMPILE_TIME_ASSERT only works in function context. These
776 	 * checks verifies that the offsets used in assembly code matches
777 	 * what's used in C code.
778 	 */
779 #ifdef ARM32
780 	COMPILE_TIME_ASSERT(offsetof(struct thread_svc_regs, r0) ==
781 				THREAD_SVC_REG_R0_OFFS);
782 	COMPILE_TIME_ASSERT(offsetof(struct thread_svc_regs, r1) ==
783 				THREAD_SVC_REG_R1_OFFS);
784 	COMPILE_TIME_ASSERT(offsetof(struct thread_svc_regs, r2) ==
785 				THREAD_SVC_REG_R2_OFFS);
786 	COMPILE_TIME_ASSERT(offsetof(struct thread_svc_regs, r3) ==
787 				THREAD_SVC_REG_R3_OFFS);
788 	COMPILE_TIME_ASSERT(offsetof(struct thread_svc_regs, r4) ==
789 				THREAD_SVC_REG_R4_OFFS);
790 	COMPILE_TIME_ASSERT(offsetof(struct thread_svc_regs, r5) ==
791 				THREAD_SVC_REG_R5_OFFS);
792 	COMPILE_TIME_ASSERT(offsetof(struct thread_svc_regs, r6) ==
793 				THREAD_SVC_REG_R6_OFFS);
794 	COMPILE_TIME_ASSERT(offsetof(struct thread_svc_regs, r7) ==
795 				THREAD_SVC_REG_R7_OFFS);
796 	COMPILE_TIME_ASSERT(offsetof(struct thread_svc_regs, lr) ==
797 				THREAD_SVC_REG_LR_OFFS);
798 	COMPILE_TIME_ASSERT(offsetof(struct thread_svc_regs, spsr) ==
799 				THREAD_SVC_REG_SPSR_OFFS);
800 #endif /*ARM32*/
801 #ifdef ARM64
802 	/* struct thread_abort_regs */
803 	COMPILE_TIME_ASSERT(offsetof(struct thread_abort_regs, x22) ==
804 			    THREAD_ABT_REG_X_OFFS(22));
805 	COMPILE_TIME_ASSERT(offsetof(struct thread_abort_regs, elr) ==
806 			    THREAD_ABT_REG_ELR_OFFS);
807 	COMPILE_TIME_ASSERT(offsetof(struct thread_abort_regs, spsr) ==
808 			    THREAD_ABT_REG_SPSR_OFFS);
809 	COMPILE_TIME_ASSERT(offsetof(struct thread_abort_regs, sp_el0) ==
810 			    THREAD_ABT_REG_SP_EL0_OFFS);
811 	COMPILE_TIME_ASSERT(sizeof(struct thread_abort_regs) ==
812 			    THREAD_ABT_REGS_SIZE);
813 
814 	/* struct thread_ctx */
815 	COMPILE_TIME_ASSERT(offsetof(struct thread_ctx, kern_sp) ==
816 			    THREAD_CTX_KERN_SP_OFFSET);
817 	COMPILE_TIME_ASSERT(sizeof(struct thread_ctx) == THREAD_CTX_SIZE);
818 
819 	/* struct thread_ctx_regs */
820 	COMPILE_TIME_ASSERT(offsetof(struct thread_ctx_regs, sp) ==
821 			    THREAD_CTX_REGS_SP_OFFSET);
822 	COMPILE_TIME_ASSERT(offsetof(struct thread_ctx_regs, pc) ==
823 			    THREAD_CTX_REGS_PC_OFFSET);
824 	COMPILE_TIME_ASSERT(offsetof(struct thread_ctx_regs, cpsr) ==
825 			    THREAD_CTX_REGS_SPSR_OFFSET);
826 	COMPILE_TIME_ASSERT(offsetof(struct thread_ctx_regs, x[23]) ==
827 			    THREAD_CTX_REGS_X_OFFSET(23));
828 	COMPILE_TIME_ASSERT(sizeof(struct thread_ctx_regs) ==
829 			    THREAD_CTX_REGS_SIZE);
830 
831 	/* struct thread_user_mode_rec */
832 	COMPILE_TIME_ASSERT(
833 		offsetof(struct thread_user_mode_rec, exit_status0_ptr) ==
834 		THREAD_USER_MODE_REC_EXIT_STATUS0_PTR_OFFSET);
835 	COMPILE_TIME_ASSERT(
836 		offsetof(struct thread_user_mode_rec, exit_status1_ptr) ==
837 		THREAD_USER_MODE_REC_EXIT_STATUS1_PTR_OFFSET);
838 	COMPILE_TIME_ASSERT(
839 		offsetof(struct thread_user_mode_rec, x[1]) ==
840 		THREAD_USER_MODE_REC_X_OFFSET(20));
841 	COMPILE_TIME_ASSERT(sizeof(struct thread_user_mode_rec) ==
842 			    THREAD_USER_MODE_REC_SIZE);
843 
844 	/* struct thread_core_local */
845 	COMPILE_TIME_ASSERT(
846 		offsetof(struct thread_core_local, tmp_stack_va_end) ==
847 		THREAD_CORE_LOCAL_TMP_STACK_VA_END_OFFSET);
848 	COMPILE_TIME_ASSERT(
849 		offsetof(struct thread_core_local, curr_thread) ==
850 		THREAD_CORE_LOCAL_CURR_THREAD_OFFSET);
851 	COMPILE_TIME_ASSERT(
852 		offsetof(struct thread_core_local, flags) ==
853 		THREAD_CORE_LOCAL_FLAGS_OFFSET);
854 	COMPILE_TIME_ASSERT(
855 		offsetof(struct thread_core_local, abt_stack_va_end) ==
856 		THREAD_CORE_LOCAL_ABT_STACK_VA_END_OFFSET);
857 	COMPILE_TIME_ASSERT(
858 		offsetof(struct thread_core_local, x[3]) ==
859 		THREAD_CORE_LOCAL_X_OFFSET(3));
860 	COMPILE_TIME_ASSERT(sizeof(struct thread_core_local) ==
861 		THREAD_CORE_LOCAL_SIZE);
862 
863 #endif /*ARM64*/
864 
865 	init_handlers(handlers);
866 
867 	/* Initialize canaries around the stacks */
868 	init_canaries();
869 
870 	for (n = 0; n < CFG_NUM_THREADS; n++)
871 		TAILQ_INIT(&threads[n].mutexes);
872 
873 	init_thread_stacks();
874 }
875 
876 static void init_sec_mon(size_t __unused pos)
877 {
878 #if !defined(CFG_WITH_ARM_TRUSTED_FW)
879 	/* Initialize secure monitor */
880 	sm_init(GET_STACK(stack_sm[pos]));
881 	sm_set_entry_vector(thread_vector_table);
882 #endif
883 }
884 
885 void thread_init_per_cpu(void)
886 {
887 	size_t pos = get_core_pos();
888 	struct thread_core_local *l = thread_get_core_local();
889 
890 	init_sec_mon(pos);
891 
892 	l->curr_thread = -1;
893 	set_tmp_stack(l, GET_STACK(stack_tmp[pos]));
894 	set_abt_stack(l, GET_STACK(stack_abt[pos]));
895 
896 	thread_init_vbar();
897 }
898 
899 void thread_set_tsd(void *tsd)
900 {
901 	/* thread_get_core_local() requires IRQs to be disabled */
902 	uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ);
903 	struct thread_core_local *l;
904 	int ct;
905 
906 	l = thread_get_core_local();
907 	ct = l->curr_thread;
908 
909 	assert(ct != -1);
910 	assert(threads[ct].state == THREAD_STATE_ACTIVE);
911 	threads[ct].tsd = tsd;
912 
913 	thread_unmask_exceptions(exceptions);
914 }
915 
916 void *thread_get_tsd(void)
917 {
918 	/* thread_get_core_local() requires IRQs to be disabled */
919 	uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ);
920 	struct thread_core_local *l;
921 	int ct;
922 	void *tsd;
923 
924 	l = thread_get_core_local();
925 	ct = l->curr_thread;
926 
927 	if (ct == -1 || threads[ct].state != THREAD_STATE_ACTIVE)
928 		tsd = NULL;
929 	else
930 		tsd = threads[ct].tsd;
931 
932 	thread_unmask_exceptions(exceptions);
933 	return tsd;
934 }
935 
936 struct thread_ctx_regs *thread_get_ctx_regs(void)
937 {
938 	struct thread_core_local *l = thread_get_core_local();
939 
940 	assert(l->curr_thread != -1);
941 	return &threads[l->curr_thread].regs;
942 }
943 
944 void thread_set_irq(bool enable)
945 {
946 	/* thread_get_core_local() requires IRQs to be disabled */
947 	uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ);
948 	struct thread_core_local *l;
949 
950 	l = thread_get_core_local();
951 
952 	assert(l->curr_thread != -1);
953 
954 	if (enable) {
955 		threads[l->curr_thread].flags |= THREAD_FLAGS_IRQ_ENABLE;
956 		thread_set_exceptions(exceptions & ~THREAD_EXCP_IRQ);
957 	} else {
958 		/*
959 		 * No need to disable IRQ here since it's already disabled
960 		 * above.
961 		 */
962 		threads[l->curr_thread].flags &= ~THREAD_FLAGS_IRQ_ENABLE;
963 	}
964 }
965 
966 void thread_restore_irq(void)
967 {
968 	/* thread_get_core_local() requires IRQs to be disabled */
969 	uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ);
970 	struct thread_core_local *l;
971 
972 	l = thread_get_core_local();
973 
974 	assert(l->curr_thread != -1);
975 
976 	if (threads[l->curr_thread].flags & THREAD_FLAGS_IRQ_ENABLE)
977 		thread_set_exceptions(exceptions & ~THREAD_EXCP_IRQ);
978 }
979 
980 #ifdef CFG_WITH_VFP
981 uint32_t thread_kernel_enable_vfp(void)
982 {
983 	uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ);
984 
985 	assert(!vfp_is_enabled());
986 
987 	if (!thread_vfp_state.ns_saved) {
988 		vfp_lazy_save_state_final(&thread_vfp_state.ns);
989 		thread_vfp_state.ns_saved = true;
990 	} else if (thread_vfp_state.sec_lazy_saved &&
991 		   !thread_vfp_state.sec_saved) {
992 		vfp_lazy_save_state_final(&thread_vfp_state.sec);
993 		thread_vfp_state.sec_saved = true;
994 	}
995 
996 	vfp_enable();
997 	return exceptions;
998 }
999 
1000 void thread_kernel_disable_vfp(uint32_t state)
1001 {
1002 	uint32_t exceptions;
1003 
1004 	assert(vfp_is_enabled());
1005 
1006 	vfp_disable();
1007 	exceptions = thread_get_exceptions();
1008 	assert(exceptions & THREAD_EXCP_IRQ);
1009 	exceptions &= ~THREAD_EXCP_IRQ;
1010 	exceptions |= state & THREAD_EXCP_IRQ;
1011 	thread_set_exceptions(exceptions);
1012 }
1013 #endif /*CFG_WITH_VFP*/
1014 
1015 void thread_add_mutex(struct mutex *m)
1016 {
1017 	struct thread_core_local *l = thread_get_core_local();
1018 	int ct = l->curr_thread;
1019 
1020 	assert(ct != -1 && threads[ct].state == THREAD_STATE_ACTIVE);
1021 	assert(m->owner_id == -1);
1022 	m->owner_id = ct;
1023 	TAILQ_INSERT_TAIL(&threads[ct].mutexes, m, link);
1024 }
1025 
1026 void thread_rem_mutex(struct mutex *m)
1027 {
1028 	struct thread_core_local *l = thread_get_core_local();
1029 	int ct = l->curr_thread;
1030 
1031 	assert(ct != -1 && threads[ct].state == THREAD_STATE_ACTIVE);
1032 	assert(m->owner_id == ct);
1033 	m->owner_id = -1;
1034 	TAILQ_REMOVE(&threads[ct].mutexes, m, link);
1035 }
1036 
1037 static bool may_unlock_big_lock(void)
1038 {
1039 	uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ);
1040 	struct thread_core_local *l = thread_get_core_local();
1041 	int ct = l->curr_thread;
1042 	struct mutex *m;
1043 	bool have_bl = false;
1044 	bool have_other = false;
1045 
1046 	TAILQ_FOREACH(m, &threads[ct].mutexes, link) {
1047 		if (m == &thread_big_lock)
1048 			have_bl = true;
1049 		else
1050 			have_other = true;
1051 	}
1052 
1053 	thread_unmask_exceptions(exceptions);
1054 	return have_bl && !have_other;
1055 }
1056 
1057 void thread_take_big_lock(void)
1058 {
1059 	mutex_lock(&thread_big_lock);
1060 }
1061 
1062 void thread_release_big_lock(void)
1063 {
1064 	assert(may_unlock_big_lock());
1065 	mutex_unlock(&thread_big_lock);
1066 }
1067 
1068 paddr_t thread_rpc_alloc_arg(size_t size)
1069 {
1070 	uint32_t rpc_args[THREAD_RPC_NUM_ARGS] = {
1071 		TEESMC_RETURN_RPC_ALLOC_ARG, size};
1072 
1073 	thread_rpc(rpc_args);
1074 	return rpc_args[1];
1075 }
1076 
1077 paddr_t thread_rpc_alloc_payload(size_t size)
1078 {
1079 	uint32_t rpc_args[THREAD_RPC_NUM_ARGS] = {
1080 		TEESMC_RETURN_RPC_ALLOC_PAYLOAD, size};
1081 
1082 	thread_rpc(rpc_args);
1083 	return rpc_args[1];
1084 }
1085 
1086 void thread_rpc_free_arg(paddr_t arg)
1087 {
1088 	if (arg) {
1089 		uint32_t rpc_args[THREAD_RPC_NUM_ARGS] = {
1090 			TEESMC_RETURN_RPC_FREE_ARG, arg};
1091 
1092 		thread_rpc(rpc_args);
1093 	}
1094 }
1095 void thread_rpc_free_payload(paddr_t payload)
1096 {
1097 	if (payload) {
1098 		uint32_t rpc_args[THREAD_RPC_NUM_ARGS] = {
1099 			TEESMC_RETURN_RPC_FREE_PAYLOAD, payload};
1100 
1101 		thread_rpc(rpc_args);
1102 	}
1103 }
1104 
1105 static uint32_t rpc_cmd_nolock(uint32_t cmd, size_t num_params,
1106 		struct teesmc32_param *params)
1107 {
1108 	uint32_t rpc_args[THREAD_RPC_NUM_ARGS] = { 0 };
1109 	struct thread_ctx *thr = threads + thread_get_id();
1110 	struct teesmc32_arg *arg = thr->rpc_arg;
1111 	paddr_t parg = thr->rpc_parg;
1112 	const size_t params_size = sizeof(struct teesmc32_param) * num_params;
1113 	size_t n;
1114 
1115 	TEE_ASSERT(arg && parg && num_params <= RPC_MAX_PARAMS);
1116 
1117 	memset(arg, 0, TEESMC32_GET_ARG_SIZE(RPC_MAX_PARAMS));
1118 	arg->cmd = cmd;
1119 	arg->ret = TEE_ERROR_GENERIC; /* in case value isn't updated */
1120 	arg->num_params = num_params;
1121 	memcpy(TEESMC32_GET_PARAMS(arg), params, params_size);
1122 
1123 	rpc_args[0] = TEESMC_RETURN_RPC_CMD;
1124 	rpc_args[1] = parg;
1125 	thread_rpc(rpc_args);
1126 
1127 	for (n = 0; n < num_params; n++) {
1128 		switch (params[n].attr & TEESMC_ATTR_TYPE_MASK) {
1129 		case TEESMC_ATTR_TYPE_VALUE_OUTPUT:
1130 		case TEESMC_ATTR_TYPE_VALUE_INOUT:
1131 		case TEESMC_ATTR_TYPE_MEMREF_OUTPUT:
1132 		case TEESMC_ATTR_TYPE_MEMREF_INOUT:
1133 			memcpy(params + n, TEESMC32_GET_PARAMS(arg) + n,
1134 			       sizeof(struct teesmc32_param));
1135 			break;
1136 		default:
1137 			break;
1138 		}
1139 	}
1140 
1141 	return arg->ret;
1142 }
1143 
1144 uint32_t thread_rpc_cmd(uint32_t cmd, size_t num_params,
1145 		struct teesmc32_param *params)
1146 {
1147 	bool unlock_big_lock = may_unlock_big_lock();
1148 	uint32_t ret;
1149 
1150 	/*
1151 	 * If current thread doesn't hold any other mutexes:
1152 	 * Let other threads get the big lock to do some work while this
1153 	 * thread is doing some potentially slow RPC in normal world.
1154 	 */
1155 	if (unlock_big_lock)
1156 		mutex_unlock(&thread_big_lock);
1157 
1158 	ret = rpc_cmd_nolock(cmd, num_params, params);
1159 
1160 	if (unlock_big_lock)
1161 		mutex_lock(&thread_big_lock);
1162 
1163 	return ret;
1164 }
1165 
1166 void thread_optee_rpc_alloc_payload(size_t size, paddr_t *payload,
1167 		paddr_t *cookie)
1168 {
1169 	uint32_t rpc_args[THREAD_RPC_NUM_ARGS] = {
1170 		TEESMC_RETURN_OPTEE_RPC_ALLOC_PAYLOAD, size};
1171 
1172 	thread_rpc(rpc_args);
1173 	if (payload)
1174 		*payload = rpc_args[1];
1175 	if (cookie)
1176 		*cookie = rpc_args[2];
1177 }
1178 
1179 void thread_optee_rpc_free_payload(paddr_t cookie)
1180 {
1181 	uint32_t rpc_args[THREAD_RPC_NUM_ARGS] ={
1182 		TEESMC_RETURN_OPTEE_RPC_FREE_PAYLOAD, cookie};
1183 
1184 	thread_rpc(rpc_args);
1185 }
1186