summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasily Gorbik <gor@linux.ibm.com>2024-11-20 21:46:17 +0100
committerAlexander Gordeev <agordeev@linux.ibm.com>2025-01-26 17:24:01 +0100
commitc09f8d0ad673afdfd5d097d95d2026a84fa4926e (patch)
tree4f802571b390d956d9ee1435a95437b4b9c1de2c
parent847e5a4c713747e8c0e9e25bda00aea782d1062b (diff)
s390/boot: Defer boot messages when earlyprintk is not enabled
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>
-rw-r--r--arch/s390/boot/ipl_parm.c2
-rw-r--r--arch/s390/boot/printk.c9
-rw-r--r--arch/s390/include/asm/boot_data.h1
-rw-r--r--arch/s390/kernel/setup.c18
4 files changed, 28 insertions, 2 deletions
diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c
index 3f775bd6d9a2..fd4874ab30cb 100644
--- a/arch/s390/boot/ipl_parm.c
+++ b/arch/s390/boot/ipl_parm.c
@@ -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"))
diff --git a/arch/s390/boot/printk.c b/arch/s390/boot/printk.c
index 311fb45c097c..7b7203f078c8 100644
--- a/arch/s390/boot/printk.c
+++ b/arch/s390/boot/printk.c
@@ -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));
}
diff --git a/arch/s390/include/asm/boot_data.h b/arch/s390/include/asm/boot_data.h
index 2cc35e968ff5..e7ef7524b847 100644
--- a/arch/s390/include/asm/boot_data.h
+++ b/arch/s390/include/asm/boot_data.h
@@ -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) \
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 0ce550faf073..feff1bb9ac2d 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -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);
@@ -878,6 +882,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());