xref: /optee_os/core/kernel/panic.c (revision bce2f88ab347b28f4149dacef2ad48ac67a500b6)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2016, Linaro Limited
4  * Copyright (c) 2014, STMicroelectronics International N.V.
5  */
6 
7 #include <initcall.h>
8 #include <kernel/interrupt.h>
9 #include <kernel/misc.h>
10 #include <kernel/panic.h>
11 #include <kernel/thread.h>
12 #include <kernel/unwind.h>
13 #include <trace.h>
14 
15 /* SGI number chosen to halt other cores must be in the secure SGI range */
16 static_assert(!IS_ENABLED(CFG_HALT_CORES_ON_PANIC) ||
17 	      (CFG_HALT_CORES_ON_PANIC_SGI >= 8 &&
18 	       CFG_HALT_CORES_ON_PANIC_SGI < 16));
19 
20 static enum itr_return __noreturn
21 multi_core_panic_it_handler(struct itr_handler *hdl __unused)
22 {
23 	IMSG("Halting CPU %zu", get_core_pos());
24 
25 	while (true)
26 		cpu_idle();
27 }
28 
29 static struct itr_handler multi_core_panic_handler = {
30 	.it = CFG_HALT_CORES_ON_PANIC_SGI,
31 	.handler = multi_core_panic_it_handler,
32 };
33 DECLARE_KEEP_PAGER(multi_core_panic_handler);
34 
35 static void notify_other_cores(void)
36 {
37 	interrupt_raise_sgi(interrupt_get_main_chip(),
38 			    CFG_HALT_CORES_ON_PANIC_SGI,
39 			    ITR_CPU_MASK_TO_OTHER_CPUS);
40 }
41 
42 static TEE_Result init_multi_core_panic_handler(void)
43 {
44 	if (!IS_ENABLED(CFG_HALT_CORES_ON_PANIC) || CFG_TEE_CORE_NB_CORE == 1)
45 		return TEE_SUCCESS;
46 
47 	if (interrupt_add_handler_with_chip(interrupt_get_main_chip(),
48 					    &multi_core_panic_handler))
49 		panic();
50 
51 	interrupt_enable(interrupt_get_main_chip(),
52 			 multi_core_panic_handler.it);
53 
54 	return TEE_SUCCESS;
55 }
56 
57 boot_final(init_multi_core_panic_handler);
58 
59 void __do_panic(const char *file __maybe_unused,
60 		const int line __maybe_unused,
61 		const char *func __maybe_unused,
62 		const char *msg __maybe_unused)
63 {
64 	/* disable prehemption */
65 	(void)thread_mask_exceptions(THREAD_EXCP_ALL);
66 
67 	/* trace: Panic ['panic-string-message' ]at FILE:LINE [<FUNCTION>]" */
68 	if (!file && !func && !msg)
69 		EMSG_RAW("Panic");
70 	else
71 		EMSG_RAW("Panic %s%s%sat %s:%d %s%s%s",
72 			 msg ? "'" : "", msg ? msg : "", msg ? "' " : "",
73 			 file ? file : "?", file ? line : 0,
74 			 func ? "<" : "", func ? func : "", func ? ">" : "");
75 
76 	print_kernel_stack();
77 
78 	if (IS_ENABLED(CFG_HALT_CORES_ON_PANIC) && CFG_TEE_CORE_NB_CORE > 1)
79 		notify_other_cores();
80 
81 	/* abort current execution */
82 	while (1)
83 		cpu_idle();
84 }
85 
86 void __weak cpu_idle(void)
87 {
88 }
89