]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
s390/boot: Introduce ring buffer for boot messages
authorVasily Gorbik <gor@linux.ibm.com>
Wed, 20 Nov 2024 19:10:50 +0000 (20:10 +0100)
committerAlexander Gordeev <agordeev@linux.ibm.com>
Sun, 26 Jan 2025 16:24:00 +0000 (17:24 +0100)
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 <gor@linux.ibm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
arch/s390/boot/printk.c
arch/s390/include/asm/boot_data.h

index 7eeb43821cd0c586fab628372c9fa99648d75ddb..e49a9be6d555ec37d52d783b2bf047c074ceab58 100644 (file)
 
 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);
+       }
 }
index f7eed27b3220fcc7e3583f2889650468c7066422..2cc35e968ff533e9974e2b1555342581215fb81b 100644 (file)
@@ -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 */