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