Skip to content

Commit

Permalink
s390/boot: Add prefix filtering to bootdebug messages
Browse files Browse the repository at this point in the history
Enhance boot debugging by allowing the "bootdebug" kernel parameter to
accept an optional comma-separated list of prefixes. Only debug messages
starting with these prefixes will be printed during boot. For example:

    bootdebug=startup,vmem

Not specifying a filter for the "bootdebug" parameter prints all debug
messages. The `boot_fmt` macro can be defined to set a common prefix:

    #define boot_fmt(fmt) "startup: " fmt

Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
  • Loading branch information
Vasily Gorbik authored and Alexander Gordeev committed Jan 26, 2025
1 parent d20d8e5 commit b79015a
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 14 deletions.
20 changes: 12 additions & 8 deletions arch/s390/boot/boot.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,18 @@ void print_stacktrace(unsigned long sp);
void error(char *m);
int get_random(unsigned long limit, unsigned long *value);

#define boot_emerg(fmt, ...) boot_printk(KERN_EMERG fmt, ##__VA_ARGS__)
#define boot_alert(fmt, ...) boot_printk(KERN_ALERT fmt, ##__VA_ARGS__)
#define boot_crit(fmt, ...) boot_printk(KERN_CRIT fmt, ##__VA_ARGS__)
#define boot_err(fmt, ...) boot_printk(KERN_ERR fmt, ##__VA_ARGS__)
#define boot_warn(fmt, ...) boot_printk(KERN_WARNING fmt, ##__VA_ARGS__)
#define boot_notice(fmt, ...) boot_printk(KERN_NOTICE fmt, ##__VA_ARGS__)
#define boot_info(fmt, ...) boot_printk(KERN_INFO fmt, ##__VA_ARGS__)
#define boot_debug(fmt, ...) boot_printk(KERN_DEBUG fmt, ##__VA_ARGS__)
#ifndef boot_fmt
#define boot_fmt(fmt) fmt
#endif

#define boot_emerg(fmt, ...) boot_printk(KERN_EMERG boot_fmt(fmt), ##__VA_ARGS__)
#define boot_alert(fmt, ...) boot_printk(KERN_ALERT boot_fmt(fmt), ##__VA_ARGS__)
#define boot_crit(fmt, ...) boot_printk(KERN_CRIT boot_fmt(fmt), ##__VA_ARGS__)
#define boot_err(fmt, ...) boot_printk(KERN_ERR boot_fmt(fmt), ##__VA_ARGS__)
#define boot_warn(fmt, ...) boot_printk(KERN_WARNING boot_fmt(fmt), ##__VA_ARGS__)
#define boot_notice(fmt, ...) boot_printk(KERN_NOTICE boot_fmt(fmt), ##__VA_ARGS__)
#define boot_info(fmt, ...) boot_printk(KERN_INFO boot_fmt(fmt), ##__VA_ARGS__)
#define boot_debug(fmt, ...) boot_printk(KERN_DEBUG boot_fmt(fmt), ##__VA_ARGS__)

extern struct machine_info machine;
extern int boot_console_loglevel;
Expand Down
5 changes: 4 additions & 1 deletion arch/s390/boot/ipl_parm.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,11 @@ void parse_boot_command_line(void)
boot_earlyprintk = true;
if (!strcmp(param, "debug"))
boot_console_loglevel = CONSOLE_LOGLEVEL_DEBUG;
if (!strcmp(param, "bootdebug"))
if (!strcmp(param, "bootdebug")) {
bootdebug = true;
if (val)
strncpy(bootdebug_filter, val, sizeof(bootdebug_filter) - 1);
}
if (!strcmp(param, "quiet"))
boot_console_loglevel = CONSOLE_LOGLEVEL_QUIET;
if (!strcmp(param, "ignore_loglevel"))
Expand Down
6 changes: 4 additions & 2 deletions arch/s390/boot/printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ bool boot_ignore_loglevel;
char __bootdata(boot_rb)[PAGE_SIZE * 2];
bool __bootdata(boot_earlyprintk);
size_t __bootdata(boot_rb_off);
char __bootdata(bootdebug_filter)[128];
bool __bootdata(bootdebug);

static void boot_rb_add(const char *str, size_t len)
Expand Down Expand Up @@ -169,11 +170,12 @@ static void boot_console_earlyprintk(const char *buf)
/* always print emergency messages */
if (level > LOGLEVEL_EMERG && !boot_earlyprintk)
return;
buf = printk_skip_level(buf);
/* print debug messages only when bootdebug is enabled */
if (level == LOGLEVEL_DEBUG && !bootdebug)
if (level == LOGLEVEL_DEBUG && (!bootdebug || !bootdebug_filter_match(buf)))
return;
if (boot_ignore_loglevel || level < boot_console_loglevel)
sclp_early_printk(printk_skip_level(buf));
sclp_early_printk(buf);
}

#define va_arg_len_type(args, lenmod, typemod) \
Expand Down
25 changes: 25 additions & 0 deletions arch/s390/include/asm/boot_data.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_S390_BOOT_DATA_H

#include <linux/string.h>
#include <asm/setup.h>
#include <asm/ipl.h>

Expand All @@ -18,6 +19,7 @@ extern unsigned long early_ipl_comp_list_size;
extern char boot_rb[PAGE_SIZE * 2];
extern bool boot_earlyprintk;
extern size_t boot_rb_off;
extern char bootdebug_filter[128];
extern bool bootdebug;

#define boot_rb_foreach(cb) \
Expand All @@ -30,4 +32,27 @@ extern bool bootdebug;
cb(boot_rb + off); \
} while (0)

/*
* bootdebug_filter is a comma separated list of strings,
* where each string can be a prefix of the message.
*/
static inline bool bootdebug_filter_match(const char *buf)
{
char *p = bootdebug_filter, *s;
char *end;

if (!*p)
return true;

end = p + strlen(p);
while (p < end) {
p = skip_spaces(p);
s = memscan(p, ',', end - p);
if (!strncmp(p, buf, s - p))
return true;
p = s + 1;
}
return false;
}

#endif /* _ASM_S390_BOOT_DATA_H */
8 changes: 5 additions & 3 deletions arch/s390/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ struct oldmem_data __bootdata_preserved(oldmem_data);
char __bootdata(boot_rb)[PAGE_SIZE * 2];
bool __bootdata(boot_earlyprintk);
size_t __bootdata(boot_rb_off);
char __bootdata(bootdebug_filter)[128];
bool __bootdata(bootdebug);

unsigned long __bootdata_preserved(VMALLOC_START);
Expand Down Expand Up @@ -886,16 +887,17 @@ static void __init log_component_list(void)
* Print avoiding interpretation of % in buf and taking bootdebug option
* into consideration.
*/
static void __init print_rb_entry(char *buf)
static void __init print_rb_entry(const char *buf)
{
char fmt[] = KERN_SOH "0boot: %s";
int level = printk_get_level(buf);

if (level == KERN_DEBUG[1] && !bootdebug)
buf = printk_skip_level(buf);
if (level == KERN_DEBUG[1] && (!bootdebug || !bootdebug_filter_match(buf)))
return;

fmt[1] = level;
printk(fmt, printk_skip_level(buf));
printk(fmt, buf);
}

/*
Expand Down

0 comments on commit b79015a

Please sign in to comment.