• Rafael J. Wysocki's avatar
    ACPI: bus: Rework system-level device notification handling · c56610a8
    Rafael J. Wysocki authored
    For ACPI drivers that provide a ->notify() callback and set
    ACPI_DRIVER_ALL_NOTIFY_EVENTS in their flags, that callback can be
    invoked while either the ->add() or the ->remove() callback is running
    without any synchronization at the bus type level which is counter to
    the common-sense expectation that notification handling should only be
    enabled when the driver is actually bound to the device.  As a result,
    if the driver is not careful enough, it's ->notify() callback may crash
    when it is invoked too early or too late [1].
    
    This issue has been amplified by commit d6fb6ee1 ("ACPI: bus: Drop
    driver member of struct acpi_device") that made acpi_bus_notify() check
    for the presence of the driver and its ->notify() callback directly
    instead of using an extra driver pointer that was only set and cleared
    by the bus type code, but it was present before that commit although
    it was harder to reproduce then.
    
    It can be addressed by using the observation that
    acpi_device_install_notify_handler() can be modified to install the
    handler for all types of events when ACPI_DRIVER_ALL_NOTIFY_EVENTS is
    set in the driver flags, in which case acpi_bus_notify() will not need
    to invoke the driver's ->notify() callback any more and that callback
    will only be invoked after acpi_device_install_notify_handler() has run
    and before acpi_device_remove_notify_handler() runs, which implies the
    correct ordering with respect to the other ACPI driver callbacks.
    
    Modify the code accordingly and while at it, drop two redundant local
    variables from acpi_bus_notify() and turn its description comment into
    a proper kerneldoc one.
    
    Fixes: d6fb6ee1 ("ACPI: bus: Drop driver member of struct acpi_device")
    Link: https://lore.kernel.org/linux-acpi/9f6cba7a8a57e5a687c934e8e406e28c.squirrel@mail.panix.com # [1]
    Reported-by: default avatarPierre Asselin <pa@panix.com>
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    Tested-by: default avatarPierre Asselin <pa@panix.com>
    c56610a8
bus.c 37.8 KB