From 816b5feaed13946b06fb7c63b7343fbfd83e520f Mon Sep 17 00:00:00 2001 From: Vasily Gorbik Date: Wed, 20 Nov 2024 20:10:50 +0100 Subject: [PATCH] s390/boot: Introduce ring buffer for boot messages Collect all boot messages into a ring buffer independent of the current log level. This allows to retain all boot-time messages, which is particularly useful for analyzing early crashes. Signed-off-by: Vasily Gorbik Acked-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- arch/s390/boot/printk.c | 20 +++++++++++++++++++- arch/s390/include/asm/boot_data.h | 13 +++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/arch/s390/boot/printk.c b/arch/s390/boot/printk.c index 7eeb43821cd0c..e49a9be6d555e 100644 --- a/arch/s390/boot/printk.c +++ b/arch/s390/boot/printk.c @@ -13,6 +13,20 @@ int boot_console_loglevel = CONFIG_CONSOLE_LOGLEVEL_DEFAULT; bool boot_ignore_loglevel; +char boot_rb[PAGE_SIZE * 2]; +size_t boot_rb_off; + +static void boot_rb_add(const char *str, size_t len) +{ + /* leave double '\0' in the end */ + size_t avail = sizeof(boot_rb) - boot_rb_off - 1; + + /* store strings separated by '\0' */ + if (len + 1 > avail) + boot_rb_off = 0; + strcpy(boot_rb + boot_rb_off, str); + boot_rb_off += len + 1; +} const char hex_asc[] = "0123456789abcdef"; @@ -229,5 +243,9 @@ void boot_printk(const char *fmt, ...) } out: va_end(args); - boot_console_earlyprintk(buf); + len = strlen(buf); + if (len) { + boot_rb_add(buf, len); + boot_console_earlyprintk(buf); + } } diff --git a/arch/s390/include/asm/boot_data.h b/arch/s390/include/asm/boot_data.h index f7eed27b3220f..2cc35e968ff53 100644 --- a/arch/s390/include/asm/boot_data.h +++ b/arch/s390/include/asm/boot_data.h @@ -15,4 +15,17 @@ extern unsigned long ipl_cert_list_size; extern unsigned long early_ipl_comp_list_addr; extern unsigned long early_ipl_comp_list_size; +extern char boot_rb[PAGE_SIZE * 2]; +extern size_t boot_rb_off; + +#define boot_rb_foreach(cb) \ + do { \ + size_t off = boot_rb_off + strlen(boot_rb + boot_rb_off) + 1; \ + size_t len; \ + for (; off < sizeof(boot_rb) && (len = strlen(boot_rb + off)); off += len + 1) \ + cb(boot_rb + off); \ + for (off = 0; off < boot_rb_off && (len = strlen(boot_rb + off)); off += len + 1) \ + cb(boot_rb + off); \ + } while (0) + #endif /* _ASM_S390_BOOT_DATA_H */ -- 2.49.0