Commit a4912303 authored by Daniel Thompson's avatar Daniel Thompson
Browse files

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: default avatarDaniel Thompson <daniel.thompson@linaro.org>
Link: https://lore.kernel.org/r/20200430161741.1832050-1-daniel.thompson@linaro.org


Reviewed-by: default avatarDouglas Anderson <dianders@chromium.org>
parent f71fc3bc
Loading
Loading
Loading
Loading
+38 −1
Original line number Diff line number Diff line
@@ -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) {
		/*
		 * 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);