Skip to content

Commit d292dbb

Browse files
author
Peter Zijlstra
committed
bug: Add BUG_FORMAT infrastructure
Add BUG_FORMAT; an architecture opt-in feature that allows adding the WARN_printf() format string to the bug_entry table. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://patch.msgid.link/20251110115757.223371452@infradead.org
1 parent 1be1fac commit d292dbb

2 files changed

Lines changed: 39 additions & 7 deletions

File tree

include/asm-generic/bug.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ struct bug_entry {
4242
#else
4343
signed int bug_addr_disp;
4444
#endif
45+
#ifdef HAVE_ARCH_BUG_FORMAT
46+
#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
47+
const char *format;
48+
#else
49+
signed int format_disp;
50+
#endif
51+
#endif
4552
#ifdef CONFIG_DEBUG_BUGVERBOSE
4653
#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
4754
const char *file;

lib/bug.c

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,19 @@ void bug_get_file_line(struct bug_entry *bug, const char **file,
139139
#endif
140140
}
141141

142+
static const char *bug_get_format(struct bug_entry *bug)
143+
{
144+
const char *format = NULL;
145+
#ifdef HAVE_ARCH_BUG_FORMAT
146+
#ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
147+
format = (const char *)&bug->format_disp + bug->format_disp;
148+
#else
149+
format = bug->format;
150+
#endif
151+
#endif
152+
return format;
153+
}
154+
142155
struct bug_entry *find_bug(unsigned long bugaddr)
143156
{
144157
struct bug_entry *bug;
@@ -150,11 +163,19 @@ struct bug_entry *find_bug(unsigned long bugaddr)
150163
return module_find_bug(bugaddr);
151164
}
152165

166+
static void __warn_printf(const char *fmt)
167+
{
168+
if (!fmt)
169+
return;
170+
171+
printk("%s", fmt);
172+
}
173+
153174
static enum bug_trap_type __report_bug(unsigned long bugaddr, struct pt_regs *regs)
154175
{
155-
struct bug_entry *bug;
156-
const char *file;
157-
unsigned line, warning, once, done;
176+
bool warning, once, done, no_cut, has_args;
177+
const char *file, *fmt;
178+
unsigned line;
158179

159180
if (!is_valid_bugaddr(bugaddr))
160181
return BUG_TRAP_TYPE_NONE;
@@ -166,10 +187,12 @@ static enum bug_trap_type __report_bug(unsigned long bugaddr, struct pt_regs *re
166187
disable_trace_on_warning();
167188

168189
bug_get_file_line(bug, &file, &line);
190+
fmt = bug_get_format(bug);
169191

170-
warning = (bug->flags & BUGFLAG_WARNING) != 0;
171-
once = (bug->flags & BUGFLAG_ONCE) != 0;
172-
done = (bug->flags & BUGFLAG_DONE) != 0;
192+
warning = bug->flags & BUGFLAG_WARNING;
193+
once = bug->flags & BUGFLAG_ONCE;
194+
done = bug->flags & BUGFLAG_DONE;
195+
no_cut = bug->flags & BUGFLAG_NO_CUT_HERE;
173196

174197
if (warning && once) {
175198
if (done)
@@ -187,8 +210,10 @@ static enum bug_trap_type __report_bug(unsigned long bugaddr, struct pt_regs *re
187210
* "cut here" line now. WARN() issues its own "cut here" before the
188211
* extra debugging message it writes before triggering the handler.
189212
*/
190-
if ((bug->flags & BUGFLAG_NO_CUT_HERE) == 0)
213+
if (!no_cut) {
191214
printk(KERN_DEFAULT CUT_HERE);
215+
__warn_printf(fmt);
216+
}
192217

193218
if (warning) {
194219
/* this is a WARN_ON rather than BUG/BUG_ON */

0 commit comments

Comments
 (0)