linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 0/3] Prefer working VT console over SPCR and device-tree chosen stdout-path
@ 2020-03-23 10:47 Alper Nebi Yasak
  2020-03-23 10:48 ` [RFC PATCH 1/3] printk: Add function to set console to preferred console's driver Alper Nebi Yasak
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Alper Nebi Yasak @ 2020-03-23 10:47 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby, Petr Mladek, Sergey Senozhatsky
  Cc: Steven Rostedt, linux-kernel, linux-arm-kernel, Alper Nebi Yasak

I recently experienced some trouble with setting up an encrypted-root
system, my Chromebook Plus (rk3399-gru-kevin, ARM64) would appear to
hang where it should have asked for an encryption passphrase; and I
eventually figured out that the kernel preferred the serial port
(inaccessible to me) over the built-in working display/keyboard and was
probably asking there.

Running plymouth in the initramfs solves that specific problem, but
both the documentation and tty-related kconfig descriptions imply that
/dev/console should be tty0 if graphics are working, CONFIG_VT_CONSOLE
is enabled and no explicit console argument is given in the kernel
commandline.

This patchset tries to ensure that VT is preferred in those conditions
even in the presence of firmware-mandated serial consoles. These should
be applicable onto next-20200323 without conflicts (also onto v5.6-rc7
with --3way minus the references to a "has_preferred_console" var).

More discussion due to or about the console confusion on ARM64:
- My Debian bug report about the initramfs prompts [0]
- Fedora test issue arising from ARM64 QEMU machines having SPCR [1]
- Debian-installer discussion on what to do with multiple consoles [2]

[0] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=952452
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1661288
[2] https://lists.debian.org/debian-boot/2019/01/msg00184.html

Alper Nebi Yasak (3):
  printk: Add function to set console to preferred console's driver
  vt: Set as preferred console when a non-dummy backend is bound
  printk: Preset tty0 as a pseudo-preferred console

 drivers/tty/vt/vt.c     |  7 +++++
 include/linux/console.h |  1 +
 kernel/printk/printk.c  | 68 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 76 insertions(+)

-- 
2.26.0.rc2


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [RFC PATCH 1/3] printk: Add function to set console to preferred console's driver
  2020-03-23 10:47 [RFC PATCH 0/3] Prefer working VT console over SPCR and device-tree chosen stdout-path Alper Nebi Yasak
@ 2020-03-23 10:48 ` Alper Nebi Yasak
  2020-03-23 10:50 ` [RFC PATCH 2/3] vt: Set as preferred console when a non-dummy backend, is bound Alper Nebi Yasak
  2020-03-23 10:50 ` [RFC PATCH 3/3] printk: Preset tty0 as a pseudo-preferred console Alper Nebi Yasak
  2 siblings, 0 replies; 4+ messages in thread
From: Alper Nebi Yasak @ 2020-03-23 10:48 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby, Petr Mladek, Sergey Senozhatsky
  Cc: Steven Rostedt, linux-kernel, linux-arm-kernel

Currently, add_preferred_console sets a preferred console, but doesn't
actually change /dev/console to match it. That part is handled within
register_device, where a newly registered console driver will be set as
/dev/console if it matches the preferred console.

However, if the relevant driver is already registered, the only way to
set it as /dev/console is by un-registering and re-registering it. An
example is the xenfb_make_preferred_console() function:

	console_lock();
	for_each_console(c) {
		if (!strcmp(c->name, "tty") && c->index == 0)
			break;
	}
	console_unlock();
	if (c) {
		unregister_console(c);
		c->flags |= CON_CONSDEV;
		c->flags &= ~CON_PRINTBUFFER; /* don't print again */
		register_console(c);
	}

The code above was introduced in commit 9e124fe16ff2. In short, it's aim
is to set VT as the preferred console only after a working framebuffer
is registered and thus VT is not the dummy device.

This patch introduces an update_console_to_preferred function that
handles the necessary /dev/console change. With this change, the example
above can be replaced with:

	console_lock();
	add_preferred_console("tty", 0, NULL);
	update_console_to_preferred();
	console_unlock();

More importantly, these two calls can be moved to vt.c in order to bump
its priority when a non-dummy backend for it is introduced, solving that
problem in general.

Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
---
 include/linux/console.h |  1 +
 kernel/printk/printk.c  | 56 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+)

diff --git a/include/linux/console.h b/include/linux/console.h
index 75dd20650fb..4b3fa34be24 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -172,6 +172,7 @@ enum con_flush_mode {
 };
 
 extern int add_preferred_console(char *name, int idx, char *options);
+extern int update_console_to_preferred(void);
 extern void register_console(struct console *);
 extern int unregister_console(struct console *);
 extern struct console *console_drivers;
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index ad460623454..6b16c973587 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2212,12 +2212,68 @@ __setup("console=", console_setup);
  * be used by arch-specific code either to override the user or more
  * commonly to provide a default console (ie from PROM variables) when
  * the user has not supplied one.
+ *
+ * Preferences set by this function don't take effect until the next
+ * time a matching driver for the preferred console is registered. If a
+ * matching driver was already registered, @update_console_to_preferred
+ * function can be used to set that as the preferred console driver.
  */
 int add_preferred_console(char *name, int idx, char *options)
 {
 	return __add_preferred_console(name, idx, options, NULL, false);
 }
 
+/**
+ * update_console_to_preferred - set console to the preferred console's driver.
+ *
+ * Updates console_drivers and CON_CONSDEV flags so that an already
+ * registered and enabled console driver matching the preferred console
+ * is used as /dev/console.
+ *
+ * Must be called within console_lock();.
+ */
+int update_console_to_preferred(void)
+{
+	struct console_cmdline *c = NULL;
+	struct console *con = NULL;
+	struct console *tmp = NULL;
+
+	if (preferred_console >= 0)
+		c = &console_cmdline[preferred_console];
+
+	if (!c || !c->name[0])
+		return 0;
+
+	for_each_console(con) {
+		if (!con->next || !(con->next->flags & CON_ENABLED))
+			continue;
+		if (strcmp(c->name, con->next->name) != 0)
+			continue;
+		if (con->next->index >= 0 &&
+		    con->next->index != c->index)
+			continue;
+		break;
+	}
+
+	if (!con)
+		return -ENODEV;
+
+	pr_info("switching to console [%s%d]\n",
+		con->next->name, con->next->index);
+
+	tmp = con->next;
+	con->next = con->next->next;
+	tmp->next = console_drivers;
+	console_drivers = tmp;
+
+	if (console_drivers->next)
+		console_drivers->next->flags &= ~CON_CONSDEV;
+	console_drivers->flags |= CON_CONSDEV;
+	has_preferred_console = true;
+
+	return 0;
+}
+
 bool console_suspend_enabled = true;
 EXPORT_SYMBOL(console_suspend_enabled);
 
-- 
2.26.0.rc2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [RFC PATCH 2/3] vt: Set as preferred console when a non-dummy backend, is bound
  2020-03-23 10:47 [RFC PATCH 0/3] Prefer working VT console over SPCR and device-tree chosen stdout-path Alper Nebi Yasak
  2020-03-23 10:48 ` [RFC PATCH 1/3] printk: Add function to set console to preferred console's driver Alper Nebi Yasak
@ 2020-03-23 10:50 ` Alper Nebi Yasak
  2020-03-23 10:50 ` [RFC PATCH 3/3] printk: Preset tty0 as a pseudo-preferred console Alper Nebi Yasak
  2 siblings, 0 replies; 4+ messages in thread
From: Alper Nebi Yasak @ 2020-03-23 10:50 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby, Petr Mladek, Sergey Senozhatsky
  Cc: Steven Rostedt, linux-kernel, linux-arm-kernel

When a machine's device-tree has a "chosen" node with a "stdout-path"
property that specified console is added as the preferred console by
of_console_check via an add_preferred_console call. The property is
quite common in kernel device-tree definitions. As far as I can tell, it
is set to provide a reasonable default value for earlycon, and the
(usually serial) console is set as preferred to avoid output going to
VT's dummy backend instead of a working console.

However, a chosen stdout-path property is included even in device-trees
of systems that are designed to be used with a built-in display, e.g.
several ARM Chromebooks. In these cases where CONFIG_VT_CONSOLE is
enabled and no console argument is given on the kernel commandline, tty0
is still registered (presumably based on the order of of_console_check
and vt's register_console calls) but ends up not being the preferred
console.

As a result, it is possible for early userspace prompts (encryption
passphrase requests, emergency shells) to end up in a console that the
user doesn't expect or even have access to.

This patch tries to set tty0 as the /dev/console whenever a non-dummy
backend tries to register as its default, unless the preferred console
was set from the kernel commandline arguments.

On a Samsung Chromebook Plus (Google Kevin, rk3399-gru-kevin.dts), boot
messages are still visible on the framebuffer without this patch, but it
isn't the preferred console due to the device-tree having a stdout-path
property (from rk3399-gru.dtsi):

	$ sudo dmesg | grep -i "console\|printk"
	[    0.000000] printk: bootconsole [uart0] enabled
	[    0.010232] Console: colour dummy device 80x25
	[    0.015107] printk: console [tty0] enabled
	[    0.019601] printk: bootconsole [uart0] disabled
	[    7.145478] printk: console [ttyS2] enabled
	[    9.316094] Console: switching to colour frame buffer device 300x100

	$ cat /proc/consoles
	ttyS2                -W- (EC p a)    4:66
	tty0                 -WU (E     )    4:7

And on the same machine, with this patch:

	$ sudo dmesg | grep -i "console\|printk"
	[    0.000000] printk: bootconsole [uart0] enabled
	[    0.010257] Console: colour dummy device 80x25
	[    0.015132] printk: console [tty0] enabled
	[    0.019626] printk: bootconsole [uart0] disabled
	[    4.741120] printk: console [ttyS2] enabled
	[    6.779994] Console: switching to colour frame buffer device 300x100
	[    6.836117] printk: switching to console [tty0]

	$ cat /proc/consoles
	tty0                 -WU (EC    )    4:7
	ttyS2                -W- (E  p a)    4:66

Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
---
 drivers/tty/vt/vt.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index bbc26d73209..0fc462ae8b2 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3566,6 +3566,13 @@ static int do_bind_con_driver(const struct consw *csw, int first, int last,
 		pr_cont("to %s\n", desc);
 	}
 
+#ifdef CONFIG_VT_CONSOLE
+	if (!console_set_on_cmdline && deflt && conswitchp != &dummy_con) {
+		add_preferred_console("tty", 0, NULL);
+		update_console_to_preferred();
+	}
+#endif
+
 	retval = 0;
 err:
 	module_put(owner);
-- 
2.26.0.rc2



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [RFC PATCH 3/3] printk: Preset tty0 as a pseudo-preferred console
  2020-03-23 10:47 [RFC PATCH 0/3] Prefer working VT console over SPCR and device-tree chosen stdout-path Alper Nebi Yasak
  2020-03-23 10:48 ` [RFC PATCH 1/3] printk: Add function to set console to preferred console's driver Alper Nebi Yasak
  2020-03-23 10:50 ` [RFC PATCH 2/3] vt: Set as preferred console when a non-dummy backend, is bound Alper Nebi Yasak
@ 2020-03-23 10:50 ` Alper Nebi Yasak
  2 siblings, 0 replies; 4+ messages in thread
From: Alper Nebi Yasak @ 2020-03-23 10:50 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby, Petr Mladek, Sergey Senozhatsky
  Cc: Steven Rostedt, linux-kernel, linux-arm-kernel

The ACPI SPCR (Serial Port Console Redirection) table from a machine's
firmware can specify a serial console which can be used for earlycon.
However, in at least ARM64 systems the same device is also set up as the
preferred console.  Presumably due to the order of acpi_parse_spcr and
VT's register_device calls, setting the specified console as the
preferred one can prevent registering VT as a console.

This might look appropriate for machines which do not have or need
working graphics and whose users most likely have access to a serial
port. However, the use of SPCR tables may not be limited these. For
example, ARM64 QEMU virtual machines include a SPCR table regardless of
the existence of a graphics output or even the nonexistence of a serial
console. Or server hardware which has a SPCR table can be repurposed
into a workstation with the addition of a graphics card. As a result,
boot messages and early userspace prompts can go to an unexpected
console.

This patch presets tty0 as a pseudo-preferred console at compile-time to
ensure that CONFIG_VT_CONSOLE always results in the VT console getting
registered. With this, VT can get registered, these other consoles are
preferred when VT is a dummy, but we can also bump up VTs preference
when working graphics are available.

Without this patch, an ARM64 QEMU virtual machine has roughly the
following order of console events and consoles:

	$ sudo dmesg | grep -i "console\|printk"
	[    0.000000] ACPI: SPCR: console: pl011,mmio,0x9000000,9600
	[    0.000000] printk: bootconsole [pl11] enabled
	[    0.004890] Console: colour dummy device 80x25
	[    0.412252] printk: console [ttyAMA0] enabled
	[    0.416173] printk: bootconsole [pl11] disabled
	[    3.940510] Console: switching to colour frame buffer device 128x48

	$ cat /proc/consoles
	ttyAMA0              -W- (EC   a)  204:64

In addition, boot messages aren't printed to the framebuffer (as tty0 is
not registered). With this patch, boot messages are visible on the
framebuffer and the information above becomes:

	$ sudo dmesg | grep -i "console\|printk"
	[    0.000000] ACPI: SPCR: console: pl011,mmio,0x9000000,9600
	[    0.000000] printk: bootconsole [pl11] enabled
	[    0.002768] Console: colour dummy device 80x25
	[    0.004371] printk: console [tty0] enabled
	[    0.380166] printk: console [ttyAMA0] enabled
	[    0.387337] printk: bootconsole [pl11] disabled
	[    4.695030] Console: switching to colour frame buffer device 128x48
	[    4.709759] printk: switching to console [tty0]

	$ cat /proc/consoles
	tty0                 -WU (EC p  )    4:7
	ttyAMA0              -W- (E    a)  204:64

Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
---
 kernel/printk/printk.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 6b16c973587..4b05779ab69 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -277,7 +277,19 @@ static struct console *exclusive_console;
 
 #define MAX_CMDLINECONSOLES 8
 
+/*
+ * The preferred_console and has_preferred_console variables are
+ * intentionally not modified to reflect this so that the first
+ * registered console is still used as the preferred console.
+ */
+#ifdef CONFIG_VT_CONSOLE
+static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES] = {
+	[0].name = "tty",
+	[0].index = 0,
+};
+#elif
 static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
+#endif
 
 static int preferred_console = -1;
 static bool has_preferred_console;
-- 
2.26.0.rc2



^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-03-23 10:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-23 10:47 [RFC PATCH 0/3] Prefer working VT console over SPCR and device-tree chosen stdout-path Alper Nebi Yasak
2020-03-23 10:48 ` [RFC PATCH 1/3] printk: Add function to set console to preferred console's driver Alper Nebi Yasak
2020-03-23 10:50 ` [RFC PATCH 2/3] vt: Set as preferred console when a non-dummy backend, is bound Alper Nebi Yasak
2020-03-23 10:50 ` [RFC PATCH 3/3] printk: Preset tty0 as a pseudo-preferred console Alper Nebi Yasak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).