Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

efi/runtime-wrappers: Remove duplicated macro for service returning void

__efi_call_virt() exists as an alternative for efi_call_virt() for the
sole reason that ResetSystem() returns void, and so we cannot use a call
to it in the RHS of an assignment.

Given that there is only a single user, let's drop the macro, and expand
it into the caller. That way, the remaining macro can be tightened
somewhat in terms of type safety too.

Note that the use of typeof() on the runtime service invocation does not
result in an actual call being made, but it does require a few pointer
types to be fixed up and converted into the proper function pointer
prototypes.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>

+14 -24
+3 -1
arch/x86/include/asm/uv/bios.h
··· 10 10 * Copyright (c) Russ Anderson <rja@sgi.com> 11 11 */ 12 12 13 + #include <linux/efi.h> 13 14 #include <linux/rtc.h> 14 15 15 16 /* ··· 116 115 struct uv_systab { 117 116 char signature[4]; /* must be UV_SYSTAB_SIG */ 118 117 u32 revision; /* distinguish different firmware revs */ 119 - u64 function; /* BIOS runtime callback function ptr */ 118 + u64 (__efiapi *function)(enum uv_bios_cmd, ...); 119 + /* BIOS runtime callback function ptr */ 120 120 u32 size; /* systab size (starting with _VERSION_UV4) */ 121 121 struct { 122 122 u32 type:8; /* type of entry */
+1 -1
drivers/acpi/prmt.c
··· 53 53 54 54 struct prm_handler_info { 55 55 guid_t guid; 56 - void *handler_addr; 56 + efi_status_t (__efiapi *handler_addr)(u64, void *); 57 57 u64 static_data_buffer_addr; 58 58 u64 acpi_param_buffer_addr; 59 59
+6 -3
drivers/firmware/efi/runtime-wrappers.c
··· 41 41 */ 42 42 #define efi_call_virt(f, args...) \ 43 43 efi_call_virt_pointer(efi.runtime, f, args) 44 - #define __efi_call_virt(f, args...) \ 45 - __efi_call_virt_pointer(efi.runtime, f, args) 46 44 47 45 union efi_rts_args { 48 46 struct { ··· 489 491 "could not get exclusive access to the firmware\n"); 490 492 return; 491 493 } 494 + 495 + arch_efi_call_virt_setup(); 492 496 efi_rts_work.efi_rts_id = EFI_RESET_SYSTEM; 493 - __efi_call_virt(reset_system, reset_type, status, data_size, data); 497 + arch_efi_call_virt(efi.runtime, reset_system, reset_type, status, 498 + data_size, data); 499 + arch_efi_call_virt_teardown(); 500 + 494 501 up(&efi_runtime_lock); 495 502 } 496 503
+4 -19
include/linux/efi.h
··· 1170 1170 #define arch_efi_call_virt(p, f, args...) ((p)->f(args)) 1171 1171 1172 1172 /* 1173 - * Arch code can implement the following three template macros, avoiding 1174 - * reptition for the void/non-void return cases of {__,}efi_call_virt(): 1173 + * Arch code must implement the following three routines: 1175 1174 * 1176 1175 * * arch_efi_call_virt_setup() 1177 1176 * ··· 1179 1180 * 1180 1181 * * arch_efi_call_virt() 1181 1182 * 1182 - * Performs the call. The last expression in the macro must be the call 1183 - * itself, allowing the logic to be shared by the void and non-void 1184 - * cases. 1183 + * Performs the call. This routine takes a variable number of arguments so 1184 + * it must be implemented as a variadic preprocessor macro. 1185 1185 * 1186 1186 * * arch_efi_call_virt_teardown() 1187 1187 * ··· 1189 1191 1190 1192 #define efi_call_virt_pointer(p, f, args...) \ 1191 1193 ({ \ 1192 - efi_status_t __s; \ 1194 + typeof((p)->f(args)) __s; \ 1193 1195 unsigned long __flags; \ 1194 1196 \ 1195 1197 arch_efi_call_virt_setup(); \ ··· 1201 1203 arch_efi_call_virt_teardown(); \ 1202 1204 \ 1203 1205 __s; \ 1204 - }) 1205 - 1206 - #define __efi_call_virt_pointer(p, f, args...) \ 1207 - ({ \ 1208 - unsigned long __flags; \ 1209 - \ 1210 - arch_efi_call_virt_setup(); \ 1211 - \ 1212 - __flags = efi_call_virt_save_flags(); \ 1213 - arch_efi_call_virt(p, f, args); \ 1214 - efi_call_virt_check_flags(__flags, __stringify(f)); \ 1215 - \ 1216 - arch_efi_call_virt_teardown(); \ 1217 1206 }) 1218 1207 1219 1208 #define EFI_RANDOM_SEED_SIZE 32U // BLAKE2S_HASH_SIZE