• Douglas Anderson's avatar
    kgdboc: Add kgdboc_earlycon to support early kgdb using boot consoles · 22099562
    Douglas Anderson authored
    We want to enable kgdb to debug the early parts of the kernel.
    Unfortunately kgdb normally is a client of the tty API in the kernel
    and serial drivers don't register to the tty layer until fairly late
    in the boot process.
    
    Serial drivers do, however, commonly register a boot console.  Let's
    enable the kgdboc driver to work with boot consoles to provide early
    debugging.
    
    This change co-opts the existing read() function pointer that's part
    of "struct console".  It's assumed that if a boot console (with the
    flag CON_BOOT) has implemented read() that both the read() and write()
    function are polling functions.  That means they work without
    interrupts and read() will return immediately (with 0 bytes read) if
    there's nothing to read.  This should be a safe assumption since it
    appears that no current boot consoles implement read() right now and
    there seems no reason to do so unless they wanted to support
    "kgdboc_earlycon".
    
    The normal/expected way to make all this work is to use
    "kgdboc_earlycon" and "kgdboc" together.  You should point them both
    to the same physical serial connection.  At boot time, as the system
    transitions from the boot console to the normal console (and registers
    a tty), kgdb will switch over.
    
    One awkward part of all this, though, is that there can be a window
    where the boot console goes away and we can't quite transtion over to
    the main kgdboc that uses the tty layer.  There are two main problems:
    
    1. The act of registering the tty doesn't cause any call into kgdboc
       so there is a window of time when the tty is there but kgdboc's
       init code hasn't been called so we can't transition to it.
    
    2. On some serial drivers the normal console inits (and replaces the
       boot console) quite early in the system.  Presumably these drivers
       were coded up before earlycon worked as well as it does today and
       probably they don't need to do this anymore, but it causes us
       problems nontheless.
    
    Problem #1 is not too big of a deal somewhat due to the luck of probe
    ordering.  kgdboc is last in the tty/serial/Makefile so its probe gets
    right after all other tty devices.  It's not fun to rely on this, but
    it does work for the most part.
    
    Problem #2 is a big deal, but only for some serial drivers.  Other
    serial drivers end up registering the console (which gets rid of the
    boot console) and tty at nearly the same time.
    
    The way we'll deal with the window when the system has stopped using
    the boot console and the time when we're setup using the tty is to
    keep using the boot console.  This may sound surprising, but it has
    been found to work well in practice.  If it doesn't work, it shouldn't
    be too hard for a given serial driver to make it keep working.
    Specifically, it's expected that the read()/write() function provided
    in the boot console should be the same (or nearly the same) as the
    normal kgdb polling functions.  That means continuing to use them
    should work just fine.  To make things even more likely to work work
    we'll also trap the recently added exit() function in the boot console
    we're using and delay any calls to it until we're all done with the
    boot console.
    
    NOTE: there could be ways to use all this in weird / unexpected ways.
    If you do something like this, it's a bit of a buyer beware situation.
    Specifically:
    - If you specify only "kgdboc_earlycon" but not "kgdboc" then
      (depending on your serial driver) things will probably work OK, but
      you'll get a warning printed the first time you use kgdb after the
      boot console is gone.  You'd only be able to do this, of course, if
      the serial driver you're running atop provided an early boot console.
    - If your "kgdboc_earlycon" and "kgdboc" devices are not the same
      device things should work OK, but it'll be your job to switch over
      which device you're monitoring (including figuring out how to switch
      over gdb in-flight if you're using it).
    
    When trying to enable "kgdboc_earlycon" it should be noted that the
    names that are registered through the boot console layer and the tty
    layer are not the same for the same port.  For example when debugging
    on one board I'd need to pass "kgdboc_earlycon=qcom_geni
    kgdboc=ttyMSM0" to enable things properly.  Since digging up the boot
    console name is a pain and there will rarely be more than one boot
    console enabled, you can provide the "kgdboc_earlycon" parameter
    without specifying the name of the boot console.  In this case we'll
    just pick the first boot that implements read() that we find.
    
    This new "kgdboc_earlycon" parameter should be contrasted to the
    existing "ekgdboc" parameter.  While both provide a way to debug very
    early, the usage and mechanisms are quite different.  Specifically
    "kgdboc_earlycon" is meant to be used in tandem with "kgdboc" and
    there is a transition from one to the other.  The "ekgdboc" parameter,
    on the other hand, replaces the "kgdboc" parameter.  It runs the same
    logic as the "kgdboc" parameter but just relies on your TTY driver
    being present super early.  The only known usage of the old "ekgdboc"
    parameter is documented as "ekgdboc=kbd earlyprintk=vga".  It should
    be noted that "kbd" has special treatment allowing it to init early as
    a tty device.
    Signed-off-by: default avatarDouglas Anderson <dianders@chromium.org>
    Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    Tested-by: default avatarSumit Garg <sumit.garg@linaro.org>
    Link: https://lore.kernel.org/r/20200507130644.v4.8.I8fba5961bf452ab92350654aa61957f23ecf0100@changeidSigned-off-by: default avatarDaniel Thompson <daniel.thompson@linaro.org>
    22099562
debug_core.c 28 KB