MOS Source Code
Loading...
Searching...
No Matches
panic.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#include "mos/misc/power.hpp"
5
9#include <mos/misc/panic.hpp>
10#include <mos/misc/setup.hpp>
12#include <mos/syslog/printk.hpp>
13#include <mos_stdio.hpp>
14
15// stack smashing protector
17
18[[noreturn]] void __stack_chk_fail(void)
19{
20 mos_panic("Stack smashing detected!");
21}
22
27
29static bool poweroff_on_panic = false;
30
31MOS_EARLY_SETUP("poweroff_on_panic", setup_poweroff_on_panic)
32{
34 return true;
35}
36
38{
39 pr_warn("installing a new warning handler...");
40 kwarn_handler = handler;
41}
42
44{
45 pr_warn("removing warning handler...");
46 if (!kwarn_handler)
47 mos_warn("no previous warning handler installed");
49}
50
53
55{
56 const panic_point_t *point = NULL;
58 {
59 if (p->ip == ip)
60 {
61 point = p;
62 break;
63 }
64 }
65 return point;
66}
67
69{
70 const panic_point_t *point = find_panic_point(ip);
71 if (!point)
72 {
73 pr_dwarn(panic, "no panic point found for " PTR_FMT, ip);
74 return;
75 }
77}
78
80{
82
83 if (!once())
84 {
85 pr_fatal("recursive panic detected, aborting...");
86 pr_info("");
88 {
89 pr_emerg("Powering off...");
91 }
92
93 while (true)
94 ;
95 }
96
97 if (printk_unquiet())
98 pr_info("quiet mode disabled"); // was quiet
99
100 pr_emerg("");
101 pr_fatal("!!!!!!!!!!!!!!!!!!!!!!!!");
102 pr_fatal("!!!!! KERNEL PANIC !!!!!");
103 pr_fatal("!!!!!!!!!!!!!!!!!!!!!!!!");
104 pr_emerg("");
105 pr_emerg("file: %s:%llu", point->file, point->line);
106 pr_emerg("function: %s", point->func);
107 if (point->ip)
108 pr_emerg("instruction: %ps (" PTR_FMT ")", (void *) point->ip, point->ip);
109 else
110 pr_emerg("instruction: see backtrace");
111 pr_emerg("");
112
113 pr_cont("\n");
114
115 if (point->ip == 0)
116 {
117 // inline panic point
118 pr_emph("Current stack trace:");
120 }
121 else
122 {
123 if (current_cpu->interrupt_regs)
124 {
125 pr_emph("Register states before interrupt:");
126 platform_dump_regs(current_cpu->interrupt_regs);
127 pr_cont("\n");
128 pr_emph("Stack trace before interrupt");
129 platform_dump_stack(current_cpu->interrupt_regs);
130 pr_cont("\n");
131 }
132 else
133 {
134 pr_emph("No interrupt context available");
135 }
136 }
137
138 pr_cont("\n");
139
140 for (const panic_hook_t *hook = __MOS_PANIC_HOOKS_START; hook < __MOS_PANIC_HOOKS_END; hook++)
141 {
142 if (hook->enabled && !*hook->enabled)
143 continue;
144
145 pr_dinfo2(panic, "invoking panic hook '%s' at %ps", hook->name, (void *) hook);
146 hook->hook();
147 }
148
150
152 {
153 pr_emerg("Powering off...");
155 }
156
157 pr_emerg("Halting...");
159
160 while (1)
161 ;
162}
163
164void mos_kwarn(const char *func, u32 line, const char *fmt, ...)
165{
166 va_list args;
167 if (kwarn_handler)
168 {
169 va_start(args, fmt);
170 kwarn_handler(func, line, fmt, args);
171 va_end(args);
172 return;
173 }
174
175 char message[MOS_PRINTK_BUFFER_SIZE];
176 va_start(args, fmt);
178 va_end(args);
179
180 lprintk(LogLevel::WARN, "\n%s", message);
181 lprintk(LogLevel::WARN, " in function: %s (line %u)\n", func, line);
182}
void platform_halt_cpu(void)
Definition mm.cpp:66
#define mos_warn(fmt,...)
Definition assert.hpp:22
#define MOS_PRINTK_BUFFER_SIZE
Definition autoconf.h:19
char args[3][16]
Definition avr_io.c:16
MOSAPI int vsnprintf(char *__restrict buf, size_t size, const char *__restrict format, va_list args)
@ IPI_TYPE_HALT
Definition ipi.hpp:14
void ipi_send_all(ipi_type_t type)
bool cmdline_string_truthiness(mos::string_view arg, bool default_value)
Definition cmdline.cpp:83
#define unlikely(x)
Definition mos_global.h:40
#define once()
Returns true for the first call, false for all subsequent calls.
Definition mos_global.h:124
void __stack_chk_fail(void)
Definition panic.cpp:18
const panic_point_t __MOS_PANIC_LIST_START[]
void kwarn_handler_set(kmsg_handler_t *handler)
Definition panic.cpp:37
const panic_hook_t __MOS_PANIC_HOOKS_START[]
void handle_kernel_panic(const panic_point_t *point)
Definition panic.cpp:79
const panic_point_t __MOS_PANIC_LIST_END[]
Definition panic.cpp:51
static bool poweroff_on_panic
Definition panic.cpp:29
const panic_hook_t __MOS_PANIC_HOOKS_END[]
Definition panic.cpp:52
void try_handle_kernel_panics(ptr_t ip)
Definition panic.cpp:68
u64 __stack_chk_guard
Definition panic.cpp:16
static const panic_point_t * find_panic_point(ptr_t ip)
Definition panic.cpp:54
static kmsg_handler_t * kwarn_handler
Definition panic.cpp:28
void __stack_chk_fail_local(void)
Definition panic.cpp:23
void kwarn_handler_remove(void)
Definition panic.cpp:43
void mos_kwarn(const char *func, u32 line, const char *fmt,...)
Definition panic.cpp:164
#define mos_panic(fmt,...)
Definition panic.hpp:51
void kmsg_handler_t(const char *func, u32 line, const char *fmt, va_list args)
Definition panic.hpp:11
#define NULL
Definition pb_syshdr.h:46
#define current_cpu
Definition platform.hpp:32
void power_shutdown(void)
Shutdown the system.
Definition power.cpp:30
bool printk_unquiet(void)
Definition printk.cpp:92
#define pr_fatal(fmt,...)
Definition printk.hpp:40
#define pr_warn(fmt,...)
Definition printk.hpp:38
#define pr_emerg(fmt,...)
Definition printk.hpp:39
#define pr_info(fmt,...)
Definition printk.hpp:35
void lprintk(LogLevel loglevel, const char *format,...)
Definition printk.cpp:104
#define pr_cont(fmt,...)
Definition printk.hpp:41
#define pr_emph(fmt,...)
Definition printk.hpp:37
#define pr_dinfo2(feat, fmt,...)
Definition printk.hpp:27
#define pr_dwarn(feat, fmt,...)
Definition printk.hpp:30
void platform_dump_regs(const platform_regs_t *regs)
void platform_dump_stack(const platform_regs_t *regs)
void platform_interrupt_disable()
void platform_dump_current_stack()
#define MOS_EARLY_SETUP(_param, _fn)
Definition setup.hpp:29
const char * func
Definition panic.hpp:26
const char * file
Definition panic.hpp:26
#define fmt(_fmt,...)
Definition syslog.hpp:161
unsigned int u32
Definition types.h:17
#define PTR_FMT
Definition types.h:29
unsigned long ptr_t
Definition types.h:21
unsigned long long u64
Definition types.h:19