Commit a61962d8 authored by Ard Biesheuvel's avatar Ard Biesheuvel

efi: libstub: Permit mixed mode return types other than efi_status_t

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.

Also, switch to _Generic() to implement the type based compile time
conditionals, which is more concise, and distinguishes between
efi_status_t and u64 properly.
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent 70912985
...@@ -93,12 +93,6 @@ SYM_FUNC_START(__efi64_thunk) ...@@ -93,12 +93,6 @@ SYM_FUNC_START(__efi64_thunk)
movl %ebx, %fs movl %ebx, %fs
movl %ebx, %gs movl %ebx, %gs
/*
* Convert 32-bit status code into 64-bit.
*/
roll $1, %eax
rorq $1, %rax
pop %rbx pop %rbx
pop %rbp pop %rbp
RET RET
......
...@@ -178,7 +178,7 @@ struct efi_setup_data { ...@@ -178,7 +178,7 @@ struct efi_setup_data {
extern u64 efi_setup; extern u64 efi_setup;
#ifdef CONFIG_EFI #ifdef CONFIG_EFI
extern efi_status_t __efi64_thunk(u32, ...); extern u64 __efi64_thunk(u32, ...);
#define efi64_thunk(...) ({ \ #define efi64_thunk(...) ({ \
u64 __pad[3]; /* must have space for 3 args on the stack */ \ u64 __pad[3]; /* must have space for 3 args on the stack */ \
...@@ -228,16 +228,15 @@ static inline bool efi_is_native(void) ...@@ -228,16 +228,15 @@ static inline bool efi_is_native(void)
return efi_is_64bit(); return efi_is_64bit();
} }
#define efi_mixed_mode_cast(attr) \
__builtin_choose_expr( \
__builtin_types_compatible_p(u32, __typeof__(attr)), \
(unsigned long)(attr), (attr))
#define efi_table_attr(inst, attr) \ #define efi_table_attr(inst, attr) \
(efi_is_native() \ (efi_is_native() ? (inst)->attr \
? inst->attr \ : efi_mixed_table_attr((inst), attr))
: (__typeof__(inst->attr)) \
efi_mixed_mode_cast(inst->mixed_mode.attr)) #define efi_mixed_table_attr(inst, attr) \
(__typeof__(inst->attr)) \
_Generic(inst->mixed_mode.attr, \
u32: (unsigned long)(inst->mixed_mode.attr), \
default: (inst->mixed_mode.attr))
/* /*
* The following macros allow translating arguments if necessary from native to * The following macros allow translating arguments if necessary from native to
...@@ -344,31 +343,27 @@ static inline u32 efi64_convert_status(efi_status_t status) ...@@ -344,31 +343,27 @@ static inline u32 efi64_convert_status(efi_status_t status)
#define __efi_eat(...) #define __efi_eat(...)
#define __efi_eval(...) __VA_ARGS__ #define __efi_eval(...) __VA_ARGS__
/* The three macros below handle dispatching via the thunk if needed */ static inline efi_status_t __efi64_widen_efi_status(u64 status)
{
#define efi_call_proto(inst, func, ...) \ /* use rotate to move the value of bit #31 into position #63 */
(efi_is_native() \ return ror64(rol32(status, 1), 1);
? inst->func(inst, ##__VA_ARGS__) \ }
: __efi64_thunk_map(inst, func, inst, ##__VA_ARGS__))
/* The macro below handles dispatching via the thunk if needed */
#define efi_bs_call(func, ...) \
(efi_is_native() \ #define efi_fn_call(inst, func, ...) \
? efi_system_table->boottime->func(__VA_ARGS__) \ (efi_is_native() ? (inst)->func(__VA_ARGS__) \
: __efi64_thunk_map(efi_table_attr(efi_system_table, \ : efi_mixed_call((inst), func, ##__VA_ARGS__))
boottime), \
func, __VA_ARGS__)) #define efi_mixed_call(inst, func, ...) \
_Generic(inst->func(__VA_ARGS__), \
#define efi_rt_call(func, ...) \ efi_status_t: \
(efi_is_native() \ __efi64_widen_efi_status( \
? efi_system_table->runtime->func(__VA_ARGS__) \ __efi64_thunk_map(inst, func, ##__VA_ARGS__)), \
: __efi64_thunk_map(efi_table_attr(efi_system_table, \ u64: ({ BUILD_BUG(); ULONG_MAX; }), \
runtime), \ default: \
func, __VA_ARGS__)) (__typeof__(inst->func(__VA_ARGS__))) \
__efi64_thunk_map(inst, func, ##__VA_ARGS__))
#define efi_dxe_call(func, ...) \
(efi_is_native() \
? efi_dxe_table->func(__VA_ARGS__) \
: __efi64_thunk_map(efi_dxe_table, func, __VA_ARGS__))
#else /* CONFIG_EFI_MIXED */ #else /* CONFIG_EFI_MIXED */
......
...@@ -44,15 +44,23 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, ...@@ -44,15 +44,23 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
#ifndef ARCH_HAS_EFISTUB_WRAPPERS #ifndef ARCH_HAS_EFISTUB_WRAPPERS
#define efi_is_native() (true) #define efi_is_native() (true)
#define efi_bs_call(func, ...) efi_system_table->boottime->func(__VA_ARGS__) #define efi_table_attr(inst, attr) (inst)->attr
#define efi_rt_call(func, ...) efi_system_table->runtime->func(__VA_ARGS__) #define efi_fn_call(inst, func, ...) (inst)->func(__VA_ARGS__)
#define efi_dxe_call(func, ...) efi_dxe_table->func(__VA_ARGS__)
#define efi_table_attr(inst, attr) (inst->attr)
#define efi_call_proto(inst, func, ...) inst->func(inst, ##__VA_ARGS__)
#endif #endif
#define efi_call_proto(inst, func, ...) ({ \
__typeof__(inst) __inst = (inst); \
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, ...) \ #define efi_info(fmt, ...) \
efi_printk(KERN_INFO fmt, ##__VA_ARGS__) efi_printk(KERN_INFO fmt, ##__VA_ARGS__)
#define efi_warn(fmt, ...) \ #define efi_warn(fmt, ...) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment