summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasily Gorbik <gor@linux.ibm.com>2024-11-23 00:02:25 +0100
committerAlexander Gordeev <agordeev@linux.ibm.com>2025-01-26 17:24:01 +0100
commitb79015ae63d3c91f06ab78b6f06abba94fd88e12 (patch)
treeea0298832e296d021ebfb03141ced0b3985e6dbc
parentd20d8e51338fc39aedf98786a4e9b71d4af4bda7 (diff)
s390/boot: Add prefix filtering to bootdebug messages
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>
-rw-r--r--arch/s390/boot/boot.h20
-rw-r--r--arch/s390/boot/ipl_parm.c5
-rw-r--r--arch/s390/boot/printk.c6
-rw-r--r--arch/s390/include/asm/boot_data.h25
-rw-r--r--arch/s390/kernel/setup.c8
5 files changed, 50 insertions, 14 deletions
diff --git a/arch/s390/boot/boot.h b/arch/s390/boot/boot.h
index dbfba6822d6f..688fa75f8651 100644
--- a/arch/s390/boot/boot.h
+++ b/arch/s390/boot/boot.h
@@ -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;
diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c
index 397046f0c1df..d3731f2983b7 100644
--- a/arch/s390/boot/ipl_parm.c
+++ b/arch/s390/boot/ipl_parm.c
@@ -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"))
diff --git a/arch/s390/boot/printk.c b/arch/s390/boot/printk.c
index 4c60245697ab..092114e46937 100644
--- a/arch/s390/boot/printk.c
+++ b/arch/s390/boot/printk.c
@@ -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)
@@ -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) \
diff --git a/arch/s390/include/asm/boot_data.h b/arch/s390/include/asm/boot_data.h
index da5527c50738..73c441f5e99a 100644
--- a/arch/s390/include/asm/boot_data.h
+++ b/arch/s390/include/asm/boot_data.h
@@ -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>
@@ -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) \
@@ -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 */
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index dd0979182890..74e2ee75b189 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -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);
@@ -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);
}
/*