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 */     \
        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)                                     \
-       (efi_is_native()                                                \
-               ? inst->attr                                            \
-               : (__typeof__(inst->attr))                              \
-                       efi_mixed_mode_cast(inst->mixed_mode.attr))
+       (efi_is_native() ? (inst)->attr                                 \
+                        : efi_mixed_table_attr((inst), 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
 #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__))
-
-#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__))
-
-#define efi_dxe_call(func, ...)                                                \
-       (efi_is_native()                                                \
-               ? efi_dxe_table->func(__VA_ARGS__)                      \
-               : __efi64_thunk_map(efi_dxe_table, func, __VA_ARGS__))
+static inline efi_status_t __efi64_widen_efi_status(u64 status)
+{
+       /* use rotate to move the value of bit #31 into position #63 */
+       return ror64(rol32(status, 1), 1);
+}
+
+/* The macro below handles dispatching via the thunk if needed */
+
+#define efi_fn_call(inst, func, ...)                                   \
+       (efi_is_native() ? (inst)->func(__VA_ARGS__)                    \
+                        : efi_mixed_call((inst), func, ##__VA_ARGS__))
+
+#define efi_mixed_call(inst, func, ...)                                        \
+       _Generic(inst->func(__VA_ARGS__),                               \
+       efi_status_t:                                                   \
+               __efi64_widen_efi_status(                               \
+                       __efi64_thunk_map(inst, func, ##__VA_ARGS__)),  \
+       u64: ({ BUILD_BUG(); ULONG_MAX; }),                             \
+       default:                                                        \
+               (__typeof__(inst->func(__VA_ARGS__)))                   \
+                       __efi64_thunk_map(inst, func, ##__VA_ARGS__))
 
 #else /* CONFIG_EFI_MIXED */
 
 
 
 #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_table_attr(inst, attr)     (inst->attr)
-#define efi_call_proto(inst, func, ...) inst->func(inst, ##__VA_ARGS__)
+#define efi_is_native()                        (true)
+#define efi_table_attr(inst, attr)     (inst)->attr
+#define efi_fn_call(inst, func, ...)   (inst)->func(__VA_ARGS__)
 
 #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, ...) \
        efi_printk(KERN_INFO fmt, ##__VA_ARGS__)
 #define efi_warn(fmt, ...) \