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:
Родитель
f71fc3bc7b
Коммит
a4912303ac
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче