• Brian Norris's avatar
    firmware: coreboot: Register bus in module init · 65946690
    Brian Norris authored
    The coreboot_table driver registers a coreboot bus while probing a
    "coreboot_table" device representing the coreboot table memory region.
    Probing this device (i.e., registering the bus) is a dependency for the
    module_init() functions of any driver for this bus (e.g.,
    memconsole-coreboot.c / memconsole_driver_init()).
    
    With synchronous probe, this dependency works OK, as the link order in
    the Makefile ensures coreboot_table_driver_init() (and thus,
    coreboot_table_probe()) completes before a coreboot device driver tries
    to add itself to the bus.
    
    With asynchronous probe, however, coreboot_table_probe() may race with
    memconsole_driver_init(), and so we're liable to hit one of these two:
    
    1. coreboot_driver_register() eventually hits "[...] the bus was not
       initialized.", and the memconsole driver fails to register; or
    2. coreboot_driver_register() gets past #1, but still races with
       bus_register() and hits some other undefined/crashing behavior (e.g.,
       in driver_find() [1])
    
    We can resolve this by registering the bus in our initcall, and only
    deferring "device" work (scanning the coreboot memory region and
    creating sub-devices) to probe().
    
    [1] Example failure, using 'driver_async_probe=*' kernel command line:
    
    [    0.114217] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
    ...
    [    0.114307] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 6.1.0-rc1 #63
    [    0.114316] Hardware name: Google Scarlet (DT)
    ...
    [    0.114488] Call trace:
    [    0.114494]  _raw_spin_lock+0x34/0x60
    [    0.114502]  kset_find_obj+0x28/0x84
    [    0.114511]  driver_find+0x30/0x50
    [    0.114520]  driver_register+0x64/0x10c
    [    0.114528]  coreboot_driver_register+0x30/0x3c
    [    0.114540]  memconsole_driver_init+0x24/0x30
    [    0.114550]  do_one_initcall+0x154/0x2e0
    [    0.114560]  do_initcall_level+0x134/0x160
    [    0.114571]  do_initcalls+0x60/0xa0
    [    0.114579]  do_basic_setup+0x28/0x34
    [    0.114588]  kernel_init_freeable+0xf8/0x150
    [    0.114596]  kernel_init+0x2c/0x12c
    [    0.114607]  ret_from_fork+0x10/0x20
    [    0.114624] Code: 5280002b 1100054a b900092a f9800011 (885ffc01)
    [    0.114631] ---[ end trace 0000000000000000 ]---
    
    Fixes: b81e3140 ("firmware: coreboot: Make bus registration symmetric")
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarBrian Norris <briannorris@chromium.org>
    Reviewed-by: default avatarGuenter Roeck <linux@roeck-us.net>
    Reviewed-by: default avatarStephen Boyd <swboyd@chromium.org>
    Link: https://lore.kernel.org/r/20221019180934.1.If29e167d8a4771b0bf4a39c89c6946ed764817b9@changeidSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    65946690
coreboot_table.c 4.93 KB