Commit 5ada918b authored by Bernhard Walle's avatar Bernhard Walle Committed by Linus Torvalds

vt: introduce and use vt_kmsg_redirect() function

The kernel offers with TIOCL_GETKMSGREDIRECT ioctl() the possibility to
redirect the kernel messages to a specific console.

However, since it's not possible to switch to the kernel message console
after a panic(), it would be nice if the kernel would print the panic
message on the current console.

This patch series adds a new interface to access the global kmsg_redirect
variable by a function to be able to use it in code where
CONFIG_VT_CONSOLE is not set (kernel/panic.c).

This patch:

Instead of using and exporting a global value kmsg_redirect, introduce a
function vt_kmsg_redirect() that both can set and return the console where
messages are printed.

Change all users of kmsg_redirect (the VT code itself and kernel/power.c)
to the new interface.

The main advantage is that vt_kmsg_redirect() can also be used when
CONFIG_VT_CONSOLE is not set.
Signed-off-by: default avatarBernhard Walle <bernhard@bwalle.de>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent c95d1e53
...@@ -184,12 +184,10 @@ static DECLARE_WORK(console_work, console_callback); ...@@ -184,12 +184,10 @@ static DECLARE_WORK(console_work, console_callback);
* fg_console is the current virtual console, * fg_console is the current virtual console,
* last_console is the last used one, * last_console is the last used one,
* want_console is the console we want to switch to, * want_console is the console we want to switch to,
* kmsg_redirect is the console for kernel messages,
*/ */
int fg_console; int fg_console;
int last_console; int last_console;
int want_console = -1; int want_console = -1;
int kmsg_redirect;
/* /*
* For each existing display, we have a pointer to console currently visible * For each existing display, we have a pointer to console currently visible
...@@ -2434,6 +2432,37 @@ struct tty_driver *console_driver; ...@@ -2434,6 +2432,37 @@ struct tty_driver *console_driver;
#ifdef CONFIG_VT_CONSOLE #ifdef CONFIG_VT_CONSOLE
/**
* vt_kmsg_redirect() - Sets/gets the kernel message console
* @new: The new virtual terminal number or -1 if the console should stay
* unchanged
*
* By default, the kernel messages are always printed on the current virtual
* console. However, the user may modify that default with the
* TIOCL_SETKMSGREDIRECT ioctl call.
*
* This function sets the kernel message console to be @new. It returns the old
* virtual console number. The virtual terminal number 0 (both as parameter and
* return value) means no redirection (i.e. always printed on the currently
* active console).
*
* The parameter -1 means that only the current console is returned, but the
* value is not modified. You may use the macro vt_get_kmsg_redirect() in that
* case to make the code more understandable.
*
* When the kernel is compiled without CONFIG_VT_CONSOLE, this function ignores
* the parameter and always returns 0.
*/
int vt_kmsg_redirect(int new)
{
static int kmsg_con;
if (new != -1)
return xchg(&kmsg_con, new);
else
return kmsg_con;
}
/* /*
* Console on virtual terminal * Console on virtual terminal
* *
...@@ -2448,6 +2477,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) ...@@ -2448,6 +2477,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
const ushort *start; const ushort *start;
ushort cnt = 0; ushort cnt = 0;
ushort myx; ushort myx;
int kmsg_console;
/* console busy or not yet initialized */ /* console busy or not yet initialized */
if (!printable) if (!printable)
...@@ -2455,8 +2485,9 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) ...@@ -2455,8 +2485,9 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
if (!spin_trylock(&printing_lock)) if (!spin_trylock(&printing_lock))
return; return;
if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1)) kmsg_console = vt_get_kmsg_redirect();
vc = vc_cons[kmsg_redirect - 1].d; if (kmsg_console && vc_cons_allocated(kmsg_console - 1))
vc = vc_cons[kmsg_console - 1].d;
/* read `x' only after setting currcons properly (otherwise /* read `x' only after setting currcons properly (otherwise
the `x' macro will read the x of the foreground console). */ the `x' macro will read the x of the foreground console). */
...@@ -2613,7 +2644,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) ...@@ -2613,7 +2644,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
ret = set_vesa_blanking(p); ret = set_vesa_blanking(p);
break; break;
case TIOCL_GETKMSGREDIRECT: case TIOCL_GETKMSGREDIRECT:
data = kmsg_redirect; data = vt_get_kmsg_redirect();
ret = __put_user(data, p); ret = __put_user(data, p);
break; break;
case TIOCL_SETKMSGREDIRECT: case TIOCL_SETKMSGREDIRECT:
...@@ -2623,7 +2654,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) ...@@ -2623,7 +2654,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
if (get_user(data, p+1)) if (get_user(data, p+1))
ret = -EFAULT; ret = -EFAULT;
else else
kmsg_redirect = data; vt_kmsg_redirect(data);
} }
break; break;
case TIOCL_GETFGCONSOLE: case TIOCL_GETFGCONSOLE:
......
...@@ -350,8 +350,6 @@ extern void tty_write_flush(struct tty_struct *); ...@@ -350,8 +350,6 @@ extern void tty_write_flush(struct tty_struct *);
extern struct ktermios tty_std_termios; extern struct ktermios tty_std_termios;
extern int kmsg_redirect;
extern void console_init(void); extern void console_init(void);
extern int vcs_init(void); extern int vcs_init(void);
......
...@@ -84,4 +84,19 @@ struct vt_setactivate { ...@@ -84,4 +84,19 @@ struct vt_setactivate {
#define VT_SETACTIVATE 0x560F /* Activate and set the mode of a console */ #define VT_SETACTIVATE 0x560F /* Activate and set the mode of a console */
#ifdef CONFIG_VT_CONSOLE
extern int vt_kmsg_redirect(int new);
#else
static inline int vt_kmsg_redirect(int new)
{
return 0;
}
#endif
#define vt_get_kmsg_redirect() vt_kmsg_redirect(-1)
#endif /* _LINUX_VT_H */ #endif /* _LINUX_VT_H */
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <linux/vt_kern.h> #include <linux/vt_kern.h>
#include <linux/kbd_kern.h> #include <linux/kbd_kern.h>
#include <linux/console.h> #include <linux/vt.h>
#include <linux/module.h> #include <linux/module.h>
#include "power.h" #include "power.h"
...@@ -21,8 +21,7 @@ int pm_prepare_console(void) ...@@ -21,8 +21,7 @@ int pm_prepare_console(void)
if (orig_fgconsole < 0) if (orig_fgconsole < 0)
return 1; return 1;
orig_kmsg = kmsg_redirect; orig_kmsg = vt_kmsg_redirect(SUSPEND_CONSOLE);
kmsg_redirect = SUSPEND_CONSOLE;
return 0; return 0;
} }
...@@ -30,7 +29,7 @@ void pm_restore_console(void) ...@@ -30,7 +29,7 @@ void pm_restore_console(void)
{ {
if (orig_fgconsole >= 0) { if (orig_fgconsole >= 0) {
vt_move_to_console(orig_fgconsole, 0); vt_move_to_console(orig_fgconsole, 0);
kmsg_redirect = orig_kmsg; vt_kmsg_redirect(orig_kmsg);
} }
} }
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment