summaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/kgdboc.c
diff options
context:
space:
mode:
authorDaniel Thompson <daniel.thompson@linaro.org>2020-04-30 18:17:41 +0200
committerDaniel Thompson <daniel.thompson@linaro.org>2020-06-02 16:15:45 +0200
commita4912303ac6fede434acf5c23a9108cdaf79844a (patch)
treed1691d0b2f4795740ca5c5438b87f2d6f9a9de70 /drivers/tty/serial/kgdboc.c
parentDocumentation: kgdboc: Document new kgdboc_earlycon parameter (diff)
downloadlinux-a4912303ac6fede434acf5c23a9108cdaf79844a.tar.xz
linux-a4912303ac6fede434acf5c23a9108cdaf79844a.zip
serial: kgdboc: Allow earlycon initialization to be deferred
Currently there is no guarantee that an earlycon will be initialized before kgdboc tries to adopt it. Almost the opposite: on systems with ACPI then if earlycon has no arguments then it is guaranteed that earlycon will not be initialized. This patch mitigates the problem by giving kgdboc_earlycon a second chance during console_init(). This isn't quite as good as stopping during early parameter parsing but it is still early in the kernel boot. Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org> Link: https://lore.kernel.org/r/20200430161741.1832050-1-daniel.thompson@linaro.org Reviewed-by: Douglas Anderson <dianders@chromium.org>
Diffstat (limited to 'drivers/tty/serial/kgdboc.c')
-rw-r--r--drivers/tty/serial/kgdboc.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
index fa6f7a3e73b9..41396982e9e0 100644
--- a/drivers/tty/serial/kgdboc.c
+++ b/drivers/tty/serial/kgdboc.c
@@ -514,6 +514,10 @@ static struct kgdb_io kgdboc_earlycon_io_ops = {
.is_console = true,
};
+#define MAX_CONSOLE_NAME_LEN (sizeof((struct console *) 0)->name)
+static char kgdboc_earlycon_param[MAX_CONSOLE_NAME_LEN] __initdata;
+static bool kgdboc_earlycon_late_enable __initdata;
+
static int __init kgdboc_earlycon_init(char *opt)
{
struct console *con;
@@ -533,7 +537,23 @@ static int __init kgdboc_earlycon_init(char *opt)
}
if (!con) {
- pr_info("Couldn't find kgdb earlycon\n");
+ /*
+ * Both earlycon and kgdboc_earlycon are initialized during * early parameter parsing. We cannot guarantee earlycon gets
+ * in first and, in any case, on ACPI systems earlycon may
+ * defer its own initialization (usually to somewhere within
+ * setup_arch() ). To cope with either of these situations
+ * we can defer our own initialization to a little later in
+ * the boot.
+ */
+ if (!kgdboc_earlycon_late_enable) {
+ pr_info("No suitable earlycon yet, will try later\n");
+ if (opt)
+ strscpy(kgdboc_earlycon_param, opt,
+ sizeof(kgdboc_earlycon_param));
+ kgdboc_earlycon_late_enable = true;
+ } else {
+ pr_info("Couldn't find kgdb earlycon\n");
+ }
goto unlock;
}
@@ -556,6 +576,23 @@ unlock:
}
early_param("kgdboc_earlycon", kgdboc_earlycon_init);
+
+/*
+ * This is only intended for the late adoption of an early console.
+ *
+ * It is not a reliable way to adopt regular consoles because we can not
+ * control what order console initcalls are made and, in any case, many
+ * regular consoles are registered much later in the boot process than
+ * the console initcalls!
+ */
+static int __init kgdboc_earlycon_late_init(void)
+{
+ if (kgdboc_earlycon_late_enable)
+ kgdboc_earlycon_init(kgdboc_earlycon_param);
+ return 0;
+}
+console_initcall(kgdboc_earlycon_late_init);
+
#endif /* IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE) */
module_init(init_kgdboc);