]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
s390/early: Dump register contents and call trace for early crashes
authorHeiko Carstens <hca@linux.ibm.com>
Thu, 1 Aug 2024 15:16:12 +0000 (17:16 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Thu, 22 Aug 2024 17:28:11 +0000 (19:28 +0200)
If the early program check handler cannot resolve a program check dump
register contents and a call trace to the console before loading a disabled
wait psw. This makes debugging much easier.

Emit an extra message with early_printk() for cases where regular printk()
via the early console is not yet working so that at least some information
is available.

Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Acked-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/include/asm/setup.h
arch/s390/kernel/early.c
arch/s390/kernel/early_printk.c

index 8505737712ee85cf1fec13f4712fe58402cd2f4d..50b943f301553c5c116532d15d3585d3ca00aea1 100644 (file)
@@ -115,6 +115,8 @@ extern unsigned int console_irq;
 #define SET_CONSOLE_VT220      do { console_mode = 4; } while (0)
 #define SET_CONSOLE_HVC                do { console_mode = 5; } while (0)
 
+void register_early_console(void);
+
 #ifdef CONFIG_VMCP
 void vmcp_cma_reserve(void);
 #else
index 25ce02be77a373ae998236e1f854aa6b9b5271b6..cc4264d230196e239f8c451058b0956d1dea1813 100644 (file)
@@ -7,6 +7,7 @@
 #define KMSG_COMPONENT "setup"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/sched/debug.h>
 #include <linux/compiler.h>
 #include <linux/init.h>
 #include <linux/errno.h>
@@ -191,6 +192,15 @@ void __init __do_early_pgm_check(struct pt_regs *regs)
        }
        if (fixup_exception(regs))
                return;
+       /*
+        * Unhandled exception - system cannot continue but try to get some
+        * helpful messages to the console. Use early_printk() to print
+        * some basic information in case it is too early for printk().
+        */
+       register_early_console();
+       early_printk("PANIC: early exception %04x PSW: %016lx %016lx\n",
+                    regs->int_code & 0xffff, regs->psw.mask, regs->psw.addr);
+       show_regs(regs);
        disabled_wait();
 }
 
index d9d53f44008ac0b6f5f8e0913244f7a8489b2289..cefe020a3be3819947c385ee8ac0f0f47c4cd9ab 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/console.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <asm/setup.h>
 #include <asm/sclp.h>
 
 static void sclp_early_write(struct console *con, const char *s, unsigned int len)
@@ -20,6 +21,16 @@ static struct console sclp_early_console = {
        .index = -1,
 };
 
+void __init register_early_console(void)
+{
+       if (early_console)
+               return;
+       if (!sclp.has_linemode && !sclp.has_vt220)
+               return;
+       early_console = &sclp_early_console;
+       register_console(early_console);
+}
+
 static int __init setup_early_printk(char *buf)
 {
        if (early_console)
@@ -27,10 +38,7 @@ static int __init setup_early_printk(char *buf)
        /* Accept only "earlyprintk" and "earlyprintk=sclp" */
        if (buf && !str_has_prefix(buf, "sclp"))
                return 0;
-       if (!sclp.has_linemode && !sclp.has_vt220)
-               return 0;
-       early_console = &sclp_early_console;
-       register_console(early_console);
+       register_early_console();
        return 0;
 }
 early_param("earlyprintk", setup_early_printk);