diff options
author | Ard Biesheuvel <ardb@kernel.org> | 2023-08-08 12:47:51 +0200 |
---|---|---|
committer | Ard Biesheuvel <ardb@kernel.org> | 2023-08-22 10:39:26 +0200 |
commit | 3c17ae4161093fa2263b70064e34a033dc16fef5 (patch) | |
tree | 3bf6bdf15342a3966694904385e4072806014c12 /drivers/firmware | |
parent | e38abdab441c0dcfb8f28dd0daf1dfa44b494492 (diff) |
efi/runtime-wrappers: Don't duplicate setup/teardown code
Avoid duplicating the EFI arch setup and teardown routine calls numerous
times in efi_call_rts(). Instead, expand the efi_call_virt_pointer()
macro into efi_call_rts(), taking the pre and post parts out of the
switch.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/efi/runtime-wrappers.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index c5e0c73cc000..afe9248cc5bc 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -40,7 +40,7 @@ * code doesn't get too cluttered: */ #define efi_call_virt(f, args...) \ - efi_call_virt_pointer(efi.runtime, f, args) + arch_efi_call_virt(efi.runtime, f, args) union efi_rts_args { struct { @@ -139,7 +139,7 @@ unsigned long efi_call_virt_save_flags(void) return flags; } -void efi_call_virt_check_flags(unsigned long flags, const char *call) +void efi_call_virt_check_flags(unsigned long flags, const void *caller) { unsigned long cur_flags, mismatch; @@ -150,8 +150,8 @@ void efi_call_virt_check_flags(unsigned long flags, const char *call) return; add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_NOW_UNRELIABLE); - pr_err_ratelimited(FW_BUG "IRQ flags corrupted (0x%08lx=>0x%08lx) by EFI %s\n", - flags, cur_flags, call); + pr_err_ratelimited(FW_BUG "IRQ flags corrupted (0x%08lx=>0x%08lx) by EFI call from %pS\n", + flags, cur_flags, caller ?: __builtin_return_address(0)); arch_efi_restore_flags(flags); } @@ -211,6 +211,10 @@ static void efi_call_rts(struct work_struct *work) { const union efi_rts_args *args = efi_rts_work.args; efi_status_t status = EFI_NOT_FOUND; + unsigned long flags; + + arch_efi_call_virt_setup(); + flags = efi_call_virt_save_flags(); switch (efi_rts_work.efi_rts_id) { case EFI_GET_TIME: @@ -287,6 +291,10 @@ static void efi_call_rts(struct work_struct *work) */ pr_err("Requested executing invalid EFI Runtime Service.\n"); } + + efi_call_virt_check_flags(flags, efi_rts_work.caller); + arch_efi_call_virt_teardown(); + efi_rts_work.status = status; complete(&efi_rts_work.efi_rts_comp); } @@ -296,6 +304,7 @@ static efi_status_t __efi_queue_work(enum efi_rts_ids id, { efi_rts_work.efi_rts_id = id; efi_rts_work.args = args; + efi_rts_work.caller = __builtin_return_address(0); efi_rts_work.status = EFI_ABORTED; if (!efi_enabled(EFI_RUNTIME_SERVICES)) { @@ -423,8 +432,8 @@ virt_efi_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor, if (down_trylock(&efi_runtime_lock)) return EFI_NOT_READY; - status = efi_call_virt(set_variable, name, vendor, attr, data_size, - data); + status = efi_call_virt_pointer(efi.runtime, set_variable, name, vendor, + attr, data_size, data); up(&efi_runtime_lock); return status; } @@ -462,8 +471,9 @@ virt_efi_query_variable_info_nonblocking(u32 attr, if (down_trylock(&efi_runtime_lock)) return EFI_NOT_READY; - status = efi_call_virt(query_variable_info, attr, storage_space, - remaining_space, max_variable_size); + status = efi_call_virt_pointer(efi.runtime, query_variable_info, attr, + storage_space, remaining_space, + max_variable_size); up(&efi_runtime_lock); return status; } |