1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
204a41849SThomas Meyer #include <linux/kmsg_dump.h>
3fdd2c1f4SJohn Ogness #include <linux/spinlock.h>
404a41849SThomas Meyer #include <linux/console.h>
5e23fe90dSThomas Meyer #include <linux/string.h>
604a41849SThomas Meyer #include <shared/init.h>
704a41849SThomas Meyer #include <shared/kern.h>
804a41849SThomas Meyer #include <os.h>
904a41849SThomas Meyer
kmsg_dumper_stdout(struct kmsg_dumper * dumper,struct kmsg_dump_detail * detail)1004a41849SThomas Meyer static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
11*e1a261baSJocelyn Falempe struct kmsg_dump_detail *detail)
1204a41849SThomas Meyer {
13f9f3f02dSJohn Ogness static struct kmsg_dump_iter iter;
14fdd2c1f4SJohn Ogness static DEFINE_SPINLOCK(lock);
1504a41849SThomas Meyer static char line[1024];
167d7c0568SAndy Shevchenko struct console *con;
17fdd2c1f4SJohn Ogness unsigned long flags;
1804a41849SThomas Meyer size_t len = 0;
1912335446SJohn Ogness int cookie;
2004a41849SThomas Meyer
213860e7c5SJohn Ogness /*
223860e7c5SJohn Ogness * If no consoles are available to output crash information, dump
233860e7c5SJohn Ogness * the kmsg buffer to stdout.
243860e7c5SJohn Ogness */
253860e7c5SJohn Ogness
2612335446SJohn Ogness cookie = console_srcu_read_lock();
2712335446SJohn Ogness for_each_console_srcu(con) {
283860e7c5SJohn Ogness /*
293860e7c5SJohn Ogness * The ttynull console and disabled consoles are ignored
303860e7c5SJohn Ogness * since they cannot output. All other consoles are
313860e7c5SJohn Ogness * expected to output the crash information.
323860e7c5SJohn Ogness */
333860e7c5SJohn Ogness if (strcmp(con->name, "ttynull") != 0 &&
3412335446SJohn Ogness (console_srcu_read_flags(con) & CON_ENABLED)) {
357d7c0568SAndy Shevchenko break;
36e23fe90dSThomas Meyer }
37e23fe90dSThomas Meyer }
3812335446SJohn Ogness console_srcu_read_unlock(cookie);
397d7c0568SAndy Shevchenko if (con)
4004a41849SThomas Meyer return;
4104a41849SThomas Meyer
42fdd2c1f4SJohn Ogness if (!spin_trylock_irqsave(&lock, flags))
43fdd2c1f4SJohn Ogness return;
44fdd2c1f4SJohn Ogness
45f9f3f02dSJohn Ogness kmsg_dump_rewind(&iter);
46f9f3f02dSJohn Ogness
4704a41849SThomas Meyer printf("kmsg_dump:\n");
48f9f3f02dSJohn Ogness while (kmsg_dump_get_line(&iter, true, line, sizeof(line), &len)) {
4904a41849SThomas Meyer line[len] = '\0';
5004a41849SThomas Meyer printf("%s", line);
5104a41849SThomas Meyer }
52fdd2c1f4SJohn Ogness
53fdd2c1f4SJohn Ogness spin_unlock_irqrestore(&lock, flags);
5404a41849SThomas Meyer }
5504a41849SThomas Meyer
5604a41849SThomas Meyer static struct kmsg_dumper kmsg_dumper = {
5704a41849SThomas Meyer .dump = kmsg_dumper_stdout
5804a41849SThomas Meyer };
5904a41849SThomas Meyer
kmsg_dumper_stdout_init(void)6053471c57STiwei Bie static int __init kmsg_dumper_stdout_init(void)
6104a41849SThomas Meyer {
6204a41849SThomas Meyer return kmsg_dump_register(&kmsg_dumper);
6304a41849SThomas Meyer }
6404a41849SThomas Meyer
6504a41849SThomas Meyer __uml_postsetup(kmsg_dumper_stdout_init);
66