kgdboc_earlycon_init() uses the console_lock to ensure that no consoles
are unregistered until the kgdboc_earlycon is setup. This is necessary
because the trapping of the exit() callback assumes that the exit()
callback is not called before the trap is setup.
Explicitly document this non-typical console_lock usage.
Signed-off-by: John Ogness <[email protected]>
---
drivers/tty/serial/kgdboc.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
index e9d3f8c6e3dc..48000666789a 100644
--- a/drivers/tty/serial/kgdboc.c
+++ b/drivers/tty/serial/kgdboc.c
@@ -545,6 +545,14 @@ static int __init kgdboc_earlycon_init(char *opt)
* Look for a matching console, or if the name was left blank just
* pick the first one we find.
*/
+
+ /*
+ * Hold the console_lock to guarantee that no consoles are
+ * unregistered until the kgdboc_earlycon setup is complete.
+ * Trapping the exit() callback relies on exit() not being
+ * called until the trap is setup. This also allows safe
+ * traversal of the console list.
+ */
console_lock();
for_each_console(con) {
if (con->write && con->read &&
--
2.30.2
On Wed, Oct 19, 2022 at 05:01:44PM +0206, John Ogness wrote:
> kgdboc_earlycon_init() uses the console_lock to ensure that no consoles
> are unregistered until the kgdboc_earlycon is setup. This is necessary
> because the trapping of the exit() callback assumes that the exit()
> callback is not called before the trap is setup.
>
> Explicitly document this non-typical console_lock usage.
>
> Signed-off-by: John Ogness <[email protected]>
> ---
> drivers/tty/serial/kgdboc.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
> index e9d3f8c6e3dc..48000666789a 100644
> --- a/drivers/tty/serial/kgdboc.c
> +++ b/drivers/tty/serial/kgdboc.c
> @@ -545,6 +545,14 @@ static int __init kgdboc_earlycon_init(char *opt)
> * Look for a matching console, or if the name was left blank just
> * pick the first one we find.
> */
> +
> + /*
> + * Hold the console_lock to guarantee that no consoles are
> + * unregistered until the kgdboc_earlycon setup is complete.
> + * Trapping the exit() callback relies on exit() not being
> + * called until the trap is setup. This also allows safe
> + * traversal of the console list.
> + */
> console_lock();
> for_each_console(con) {
> if (con->write && con->read &&
> --
> 2.30.2
>
Reviewed-by: Greg Kroah-Hartman <[email protected]>
Hi,
On Wed, Oct 19, 2022 at 7:56 AM John Ogness <[email protected]> wrote:
>
> kgdboc_earlycon_init() uses the console_lock to ensure that no consoles
> are unregistered until the kgdboc_earlycon is setup. This is necessary
> because the trapping of the exit() callback assumes that the exit()
> callback is not called before the trap is setup.
>
> Explicitly document this non-typical console_lock usage.
>
> Signed-off-by: John Ogness <[email protected]>
> ---
> drivers/tty/serial/kgdboc.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
Reviewed-by: Douglas Anderson <[email protected]>
On Wed 2022-10-19 17:01:44, John Ogness wrote:
> kgdboc_earlycon_init() uses the console_lock to ensure that no consoles
> are unregistered until the kgdboc_earlycon is setup. This is necessary
> because the trapping of the exit() callback assumes that the exit()
> callback is not called before the trap is setup.
Great catch!
Note: This behavior might be dangerous. printk_late_init() checks if
the early console code is in the init section. It unregisters
such consoles even when keep_bootcon parameter is used.
Well, it is "not serious" and might be improved later.
If the early console has this code in the early section
then it is a bug and should be fixed. printk_late_init() does
the best effort because this problem would block all consoles
and would be hard to debug. It is the same with kgdb but
it is still only a corner case and just the best effort.
> Explicitly document this non-typical console_lock usage.
>
> Signed-off-by: John Ogness <[email protected]>
Reviewed-by: Petr Mladek <[email protected]>
Best Regards,
Petr