@@ -93,12 +93,6 @@ SYM_FUNC_START(__efi64_thunk)
movl %ebx, %fs
movl %ebx, %gs
- /*
- * Convert 32-bit status code into 64-bit.
- */
- roll $1, %eax
- rorq $1, %rax
-
pop %rbx
pop %rbp
RET
@@ -178,7 +178,7 @@ struct efi_setup_data {
extern u64 efi_setup;
#ifdef CONFIG_EFI
-extern efi_status_t __efi64_thunk(u32, ...);
+extern u64 __efi64_thunk(u32, ...);
#define efi64_thunk(...) ({ \
u64 __pad[3]; /* must have space for 3 args on the stack */ \
@@ -344,31 +344,23 @@ static inline u32 efi64_convert_status(efi_status_t status)
#define __efi_eat(...)
#define __efi_eval(...) __VA_ARGS__
-/* The three macros below handle dispatching via the thunk if needed */
-
-#define efi_call_proto(inst, func, ...) \
- (efi_is_native() \
- ? inst->func(inst, ##__VA_ARGS__) \
- : __efi64_thunk_map(inst, func, inst, ##__VA_ARGS__))
-
-#define efi_bs_call(func, ...) \
- (efi_is_native() \
- ? efi_system_table->boottime->func(__VA_ARGS__) \
- : __efi64_thunk_map(efi_table_attr(efi_system_table, \
- boottime), \
- func, __VA_ARGS__))
+static inline efi_status_t __efi64_widen_efi_status(u64 status)
+{
+ return status ? status ^ 0x8000000080000000ULL : 0;
+}
-#define efi_rt_call(func, ...) \
- (efi_is_native() \
- ? efi_system_table->runtime->func(__VA_ARGS__) \
- : __efi64_thunk_map(efi_table_attr(efi_system_table, \
- runtime), \
- func, __VA_ARGS__))
+/* The macro below handles dispatching via the thunk if needed */
-#define efi_dxe_call(func, ...) \
+#define efi_fn_call(inst, func, ...) \
(efi_is_native() \
- ? efi_dxe_table->func(__VA_ARGS__) \
- : __efi64_thunk_map(efi_dxe_table, func, __VA_ARGS__))
+ ? inst->func(__VA_ARGS__) \
+ : __builtin_choose_expr( \
+ __builtin_types_compatible_p(efi_status_t, \
+ __typeof__(inst->func(__VA_ARGS__))), \
+ __efi64_widen_efi_status( \
+ __efi64_thunk_map(inst, func, ##__VA_ARGS__)), \
+ (__typeof__(inst->func(__VA_ARGS__))) \
+ __efi64_thunk_map(inst, func, ##__VA_ARGS__)))
#else /* CONFIG_EFI_MIXED */
@@ -44,15 +44,21 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
#ifndef ARCH_HAS_EFISTUB_WRAPPERS
-#define efi_is_native() (true)
-#define efi_bs_call(func, ...) efi_system_table->boottime->func(__VA_ARGS__)
-#define efi_rt_call(func, ...) efi_system_table->runtime->func(__VA_ARGS__)
-#define efi_dxe_call(func, ...) efi_dxe_table->func(__VA_ARGS__)
+#define efi_is_native() (true)
#define efi_table_attr(inst, attr) (inst->attr)
-#define efi_call_proto(inst, func, ...) inst->func(inst, ##__VA_ARGS__)
+#define efi_fn_call(inst, func, ...) inst->func(__VA_ARGS__)
#endif
+#define efi_call_proto(inst, func, ...) \
+ efi_fn_call(inst, func, inst, ##__VA_ARGS__)
+#define efi_bs_call(func, ...) \
+ efi_fn_call(efi_table_attr(efi_system_table, boottime), func, ##__VA_ARGS__)
+#define efi_rt_call(func, ...) \
+ efi_fn_call(efi_table_attr(efi_system_table, runtime), func, ##__VA_ARGS__)
+#define efi_dxe_call(func, ...) \
+ efi_fn_call(efi_dxe_table, func, ##__VA_ARGS__)
+
#define efi_info(fmt, ...) \
efi_printk(KERN_INFO fmt, ##__VA_ARGS__)
#define efi_warn(fmt, ...) \
Rework the EFI stub macro wrappers around protocol method calls and other indirect calls in order to allow return types other than efi_status_t. This means the widening should be conditional on whether or not the return type is efi_status_t, and should be omitted otherwise. Note that this does not take into account that unsigned long types might exist that are not efi_status_t, but that can be addressed when it becomes an issue. Signed-off-by: Ard Biesheuvel <ardb@kernel.org> --- arch/x86/boot/compressed/efi_thunk_64.S | 6 ---- arch/x86/include/asm/efi.h | 38 ++++++++------------ drivers/firmware/efi/libstub/efistub.h | 16 ++++++--- 3 files changed, 26 insertions(+), 34 deletions(-)