diff options
Diffstat (limited to 'kernel/debug/kdb/kdb_io.c')
| -rw-r--r-- | kernel/debug/kdb/kdb_io.c | 18 | 
1 files changed, 16 insertions, 2 deletions
| diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c index 67d3c48a1522..5c7e9ba7cd6b 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c @@ -545,6 +545,7 @@ static void kdb_msg_write(const char *msg, int msg_len)  {  	struct console *c;  	const char *cp; +	int cookie;  	int len;  	if (msg_len == 0) @@ -558,8 +559,20 @@ static void kdb_msg_write(const char *msg, int msg_len)  		cp++;  	} -	for_each_console(c) { -		if (!(c->flags & CON_ENABLED)) +	/* +	 * The console_srcu_read_lock() only provides safe console list +	 * traversal. The use of the ->write() callback relies on all other +	 * CPUs being stopped at the moment and console drivers being able to +	 * handle reentrance when @oops_in_progress is set. +	 * +	 * There is no guarantee that every console driver can handle +	 * reentrance in this way; the developer deploying the debugger +	 * is responsible for ensuring that the console drivers they +	 * have selected handle reentrance appropriately. +	 */ +	cookie = console_srcu_read_lock(); +	for_each_console_srcu(c) { +		if (!(console_srcu_read_flags(c) & CON_ENABLED))  			continue;  		if (c == dbg_io_ops->cons)  			continue; @@ -577,6 +590,7 @@ static void kdb_msg_write(const char *msg, int msg_len)  		--oops_in_progress;  		touch_nmi_watchdog();  	} +	console_srcu_read_unlock(cookie);  }  int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap) |