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>
This commit is contained in:
parent
f71fc3bc7b
commit
a4912303ac
@ -514,6 +514,10 @@ static struct kgdb_io kgdboc_earlycon_io_ops = {
|
|||||||
.is_console = true,
|
.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)
|
static int __init kgdboc_earlycon_init(char *opt)
|
||||||
{
|
{
|
||||||
struct console *con;
|
struct console *con;
|
||||||
@ -533,7 +537,23 @@ static int __init kgdboc_earlycon_init(char *opt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!con) {
|
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;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,6 +576,23 @@ unlock:
|
|||||||
}
|
}
|
||||||
|
|
||||||
early_param("kgdboc_earlycon", kgdboc_earlycon_init);
|
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) */
|
#endif /* IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE) */
|
||||||
|
|
||||||
module_init(init_kgdboc);
|
module_init(init_kgdboc);
|
||||||
|
Loading…
Reference in New Issue
Block a user