• Ard Biesheuvel's avatar
    efi: vars: Don't drop lock in the middle of efivar_init() · ec3507b2
    Ard Biesheuvel authored
    Even though the efivars_lock lock is documented as protecting the
    efivars->ops pointer (among other things), efivar_init() happily
    releases and reacquires the lock for every EFI variable that it
    enumerates. This used to be needed because the lock was originally a
    spinlock, which prevented the callback that is invoked for every
    variable from being able to sleep. However, releasing the lock could
    potentially invalidate the ops pointer, but more importantly, it might
    allow a SetVariable() runtime service call to take place concurrently,
    and the UEFI spec does not define how this affects an enumeration that
    is running in parallel using the GetNextVariable() runtime service,
    which is what efivar_init() uses.
    
    In the meantime, the lock has been converted into a semaphore, and the
    only reason we need to drop the lock is because the efivarfs pseudo
    filesystem driver will otherwise deadlock when it invokes the efivars
    API from the callback to create the efivar_entry items and insert them
    into the linked list. (EFI pstore is affected in a similar way)
    
    So let's switch to helpers that can be used while the lock is already
    taken. This way, we can hold on to the lock throughout the enumeration.
    Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
    ec3507b2
efi.h 44.4 KB