Skip to content

Commit

Permalink
serial: kgdboc: Allow earlycon initialization to be deferred
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Daniel Thompson committed Jun 2, 2020
1 parent f71fc3b commit a491230
Showing 1 changed file with 38 additions and 1 deletion.
39 changes: 38 additions & 1 deletion drivers/tty/serial/kgdboc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

Expand All @@ -556,6 +576,23 @@ static int __init kgdboc_earlycon_init(char *opt)
}

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);
Expand Down

0 comments on commit a491230

Please sign in to comment.