Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+38 -1
+38 -1
drivers/tty/serial/kgdboc.c
··· 514 514 .is_console = true, 515 515 }; 516 516 517 + #define MAX_CONSOLE_NAME_LEN (sizeof((struct console *) 0)->name) 518 + static char kgdboc_earlycon_param[MAX_CONSOLE_NAME_LEN] __initdata; 519 + static bool kgdboc_earlycon_late_enable __initdata; 520 + 517 521 static int __init kgdboc_earlycon_init(char *opt) 518 522 { 519 523 struct console *con; ··· 537 533 } 538 534 539 535 if (!con) { 540 - pr_info("Couldn't find kgdb earlycon\n"); 536 + /* 537 + * Both earlycon and kgdboc_earlycon are initialized during * early parameter parsing. We cannot guarantee earlycon gets 538 + * in first and, in any case, on ACPI systems earlycon may 539 + * defer its own initialization (usually to somewhere within 540 + * setup_arch() ). To cope with either of these situations 541 + * we can defer our own initialization to a little later in 542 + * the boot. 543 + */ 544 + if (!kgdboc_earlycon_late_enable) { 545 + pr_info("No suitable earlycon yet, will try later\n"); 546 + if (opt) 547 + strscpy(kgdboc_earlycon_param, opt, 548 + sizeof(kgdboc_earlycon_param)); 549 + kgdboc_earlycon_late_enable = true; 550 + } else { 551 + pr_info("Couldn't find kgdb earlycon\n"); 552 + } 541 553 goto unlock; 542 554 } 543 555 ··· 576 556 } 577 557 578 558 early_param("kgdboc_earlycon", kgdboc_earlycon_init); 559 + 560 + /* 561 + * This is only intended for the late adoption of an early console. 562 + * 563 + * It is not a reliable way to adopt regular consoles because we can not 564 + * control what order console initcalls are made and, in any case, many 565 + * regular consoles are registered much later in the boot process than 566 + * the console initcalls! 567 + */ 568 + static int __init kgdboc_earlycon_late_init(void) 569 + { 570 + if (kgdboc_earlycon_late_enable) 571 + kgdboc_earlycon_init(kgdboc_earlycon_param); 572 + return 0; 573 + } 574 + console_initcall(kgdboc_earlycon_late_init); 575 + 579 576 #endif /* IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE) */ 580 577 581 578 module_init(init_kgdboc);