1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/kmsg_dump.h> 3 #include <linux/spinlock.h> 4 #include <linux/console.h> 5 #include <linux/string.h> 6 #include <shared/init.h> 7 #include <shared/kern.h> 8 #include <os.h> 9 10 static void kmsg_dumper_stdout(struct kmsg_dumper *dumper, 11 enum kmsg_dump_reason reason) 12 { 13 static struct kmsg_dump_iter iter; 14 static DEFINE_SPINLOCK(lock); 15 static char line[1024]; 16 struct console *con; 17 unsigned long flags; 18 size_t len = 0; 19 int cookie; 20 21 /* 22 * If no consoles are available to output crash information, dump 23 * the kmsg buffer to stdout. 24 */ 25 26 cookie = console_srcu_read_lock(); 27 for_each_console_srcu(con) { 28 /* 29 * The ttynull console and disabled consoles are ignored 30 * since they cannot output. All other consoles are 31 * expected to output the crash information. 32 */ 33 if (strcmp(con->name, "ttynull") != 0 && 34 (console_srcu_read_flags(con) & CON_ENABLED)) { 35 break; 36 } 37 } 38 console_srcu_read_unlock(cookie); 39 if (con) 40 return; 41 42 if (!spin_trylock_irqsave(&lock, flags)) 43 return; 44 45 kmsg_dump_rewind(&iter); 46 47 printf("kmsg_dump:\n"); 48 while (kmsg_dump_get_line(&iter, true, line, sizeof(line), &len)) { 49 line[len] = '\0'; 50 printf("%s", line); 51 } 52 53 spin_unlock_irqrestore(&lock, flags); 54 } 55 56 static struct kmsg_dumper kmsg_dumper = { 57 .dump = kmsg_dumper_stdout 58 }; 59 60 int __init kmsg_dumper_stdout_init(void) 61 { 62 return kmsg_dump_register(&kmsg_dumper); 63 } 64 65 __uml_postsetup(kmsg_dumper_stdout_init); 66