xref: /linux-6.15/arch/um/kernel/kmsg_dump.c (revision e1a261ba)
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