Commit 9e124fe1 authored by Markus Armbruster's avatar Markus Armbruster Committed by Thomas Gleixner

xen: Enable console tty by default in domU if it's not a dummy

Without console= arguments on the kernel command line, the first
console to register becomes enabled and the preferred console (the one
behind /dev/console).  This is normally tty (assuming
CONFIG_VT_CONSOLE is enabled, which it commonly is).

This is okay as long tty is a useful console.  But unless we have the
PV framebuffer, and it is enabled for this domain, tty0 in domU is
merely a dummy.  In that case, we want the preferred console to be the
Xen console hvc0, and we want it without having to fiddle with the
kernel command line.  Commit b8c2d3df
did that for us.

Since we now have the PV framebuffer, we want to enable and prefer tty
again, but only when PVFB is enabled.  But even then we still want to
enable the Xen console as well.

Problem: when tty registers, we can't yet know whether the PVFB is
enabled.  By the time we can know (xenstore is up), the console setup
game is over.

Solution: enable console tty by default, but keep hvc as the preferred
console.  Change the preferred console to tty when PVFB probes
successfully, unless we've been given console kernel parameters.
Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
Signed-off-by: default avatarJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent a15af1c9
...@@ -1256,8 +1256,10 @@ asmlinkage void __init xen_start_kernel(void) ...@@ -1256,8 +1256,10 @@ asmlinkage void __init xen_start_kernel(void)
? __pa(xen_start_info->mod_start) : 0; ? __pa(xen_start_info->mod_start) : 0;
boot_params.hdr.ramdisk_size = xen_start_info->mod_len; boot_params.hdr.ramdisk_size = xen_start_info->mod_len;
if (!is_initial_xendomain()) if (!is_initial_xendomain()) {
add_preferred_console("tty", 0, NULL);
add_preferred_console("hvc", 0, NULL); add_preferred_console("hvc", 0, NULL);
}
/* Start the world */ /* Start the world */
start_kernel(); start_kernel();
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
* frame buffer. * frame buffer.
*/ */
#include <linux/console.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/fb.h> #include <linux/fb.h>
...@@ -48,6 +49,7 @@ struct xenfb_info { ...@@ -48,6 +49,7 @@ struct xenfb_info {
static u32 xenfb_mem_len = XENFB_WIDTH * XENFB_HEIGHT * XENFB_DEPTH / 8; static u32 xenfb_mem_len = XENFB_WIDTH * XENFB_HEIGHT * XENFB_DEPTH / 8;
static void xenfb_make_preferred_console(void);
static int xenfb_remove(struct xenbus_device *); static int xenfb_remove(struct xenbus_device *);
static void xenfb_init_shared_page(struct xenfb_info *); static void xenfb_init_shared_page(struct xenfb_info *);
static int xenfb_connect_backend(struct xenbus_device *, struct xenfb_info *); static int xenfb_connect_backend(struct xenbus_device *, struct xenfb_info *);
...@@ -348,6 +350,7 @@ static int __devinit xenfb_probe(struct xenbus_device *dev, ...@@ -348,6 +350,7 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
if (ret < 0) if (ret < 0)
goto error; goto error;
xenfb_make_preferred_console();
return 0; return 0;
error_nomem: error_nomem:
...@@ -358,6 +361,28 @@ static int __devinit xenfb_probe(struct xenbus_device *dev, ...@@ -358,6 +361,28 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
return ret; return ret;
} }
static __devinit void
xenfb_make_preferred_console(void)
{
struct console *c;
if (console_set_on_cmdline)
return;
acquire_console_sem();
for (c = console_drivers; c; c = c->next) {
if (!strcmp(c->name, "tty") && c->index == 0)
break;
}
release_console_sem();
if (c) {
unregister_console(c);
c->flags |= CON_CONSDEV;
c->flags &= ~CON_PRINTBUFFER; /* don't print again */
register_console(c);
}
}
static int xenfb_resume(struct xenbus_device *dev) static int xenfb_resume(struct xenbus_device *dev)
{ {
struct xenfb_info *info = dev->dev.driver_data; struct xenfb_info *info = dev->dev.driver_data;
......
...@@ -108,6 +108,8 @@ struct console { ...@@ -108,6 +108,8 @@ struct console {
struct console *next; struct console *next;
}; };
extern int console_set_on_cmdline;
extern int add_preferred_console(char *name, int idx, char *options); extern int add_preferred_console(char *name, int idx, char *options);
extern int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options); extern int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options);
extern void register_console(struct console *); extern void register_console(struct console *);
......
...@@ -121,6 +121,8 @@ struct console_cmdline ...@@ -121,6 +121,8 @@ struct console_cmdline
static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES]; static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
static int selected_console = -1; static int selected_console = -1;
static int preferred_console = -1; static int preferred_console = -1;
int console_set_on_cmdline;
EXPORT_SYMBOL(console_set_on_cmdline);
/* Flag: console code may call schedule() */ /* Flag: console code may call schedule() */
static int console_may_schedule; static int console_may_schedule;
...@@ -890,6 +892,7 @@ static int __init console_setup(char *str) ...@@ -890,6 +892,7 @@ static int __init console_setup(char *str)
*s = 0; *s = 0;
__add_preferred_console(buf, idx, options, brl_options); __add_preferred_console(buf, idx, options, brl_options);
console_set_on_cmdline = 1;
return 1; return 1;
} }
__setup("console=", console_setup); __setup("console=", console_setup);
......
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