]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
s390/boot: Defer boot messages when earlyprintk is not enabled
authorVasily Gorbik <gor@linux.ibm.com>
Wed, 20 Nov 2024 20:46:17 +0000 (21:46 +0100)
committerAlexander Gordeev <agordeev@linux.ibm.com>
Sun, 26 Jan 2025 16:24:01 +0000 (17:24 +0100)
When earlyprintk is not specified, boot messages are only stored in a
ring buffer to be printed later by printk when console driver is
registered.

Critical messages from boot_emerg() are always printed immediately,
even without earlyprintk.

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/ipl_parm.c
arch/s390/boot/printk.c
arch/s390/include/asm/boot_data.h
arch/s390/kernel/setup.c

index 3f775bd6d9a230c697c1e3c013b412a7b966d355..fd4874ab30cb7c5dd6867e6218cb01fb03e48c24 100644 (file)
@@ -313,6 +313,8 @@ void parse_boot_command_line(void)
 #endif
                if (!strcmp(param, "relocate_lowcore") && test_facility(193))
                        relocate_lowcore = 1;
+               if (!strcmp(param, "earlyprintk"))
+                       boot_earlyprintk = true;
                if (!strcmp(param, "debug"))
                        boot_console_loglevel = CONSOLE_LOGLEVEL_DEBUG;
                if (!strcmp(param, "quiet"))
index 311fb45c097c5ec9471708981077fbc440a1f2a9..7b7203f078c806aaa7564d4b4804f68ca6c7dc29 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/ctype.h>
 #include <asm/stacktrace.h>
 #include <asm/boot_data.h>
+#include <asm/sections.h>
 #include <asm/lowcore.h>
 #include <asm/setup.h>
 #include <asm/sclp.h>
@@ -13,8 +14,9 @@
 
 int boot_console_loglevel = CONFIG_CONSOLE_LOGLEVEL_DEFAULT;
 bool boot_ignore_loglevel;
-char boot_rb[PAGE_SIZE * 2];
-size_t boot_rb_off;
+char __bootdata(boot_rb)[PAGE_SIZE * 2];
+bool __bootdata(boot_earlyprintk);
+size_t __bootdata(boot_rb_off);
 
 static void boot_rb_add(const char *str, size_t len)
 {
@@ -163,6 +165,9 @@ static void boot_console_earlyprintk(const char *buf)
 {
        int level = printk_loglevel(buf);
 
+       /* always print emergency messages */
+       if (level > LOGLEVEL_EMERG && !boot_earlyprintk)
+               return;
        if (boot_ignore_loglevel || level < boot_console_loglevel)
                sclp_early_printk(printk_skip_level(buf));
 }
index 2cc35e968ff533e9974e2b1555342581215fb81b..e7ef7524b847e299293c9ed8723c5f1ece50ef90 100644 (file)
@@ -16,6 +16,7 @@ extern unsigned long early_ipl_comp_list_addr;
 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;
 
 #define boot_rb_foreach(cb)                                                    \
index 0ce550faf0733a3f27baef59fb40353f20edf1d0..feff1bb9ac2da67ab235d15c47e6b6c2a62ce3fb 100644 (file)
@@ -157,6 +157,10 @@ u64 __bootdata_preserved(stfle_fac_list[16]);
 EXPORT_SYMBOL(stfle_fac_list);
 struct oldmem_data __bootdata_preserved(oldmem_data);
 
+char __bootdata(boot_rb)[PAGE_SIZE * 2];
+bool __bootdata(boot_earlyprintk);
+size_t __bootdata(boot_rb_off);
+
 unsigned long __bootdata_preserved(VMALLOC_START);
 EXPORT_SYMBOL(VMALLOC_START);
 
@@ -877,6 +881,17 @@ static void __init log_component_list(void)
        }
 }
 
+/*
+ * Print avoiding interpretation of % in buf
+ */
+static void __init print_rb_entry(char *buf)
+{
+       char fmt[] = KERN_SOH "0boot: %s";
+
+       fmt[1] = printk_get_level(buf);
+       printk(fmt, printk_skip_level(buf));
+}
+
 /*
  * Setup function called from init/main.c just after the banner
  * was printed.
@@ -896,6 +911,9 @@ void __init setup_arch(char **cmdline_p)
                pr_info("Linux is running natively in 64-bit mode\n");
        else
                pr_info("Linux is running as a guest in 64-bit mode\n");
+       /* Print decompressor messages if not already printed */
+       if (!boot_earlyprintk)
+               boot_rb_foreach(print_rb_entry);
 
        if (have_relocated_lowcore())
                pr_info("Lowcore relocated to 0x%px\n", get_lowcore());