diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/include/asm/efi.h | 2 | ||||
-rw-r--r-- | arch/arm64/include/asm/efi.h | 2 | ||||
-rw-r--r-- | arch/x86/boot/compressed/eboot.c | 3 | ||||
-rw-r--r-- | arch/x86/include/asm/efi.h | 35 |
4 files changed, 31 insertions, 11 deletions
diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h index 2306ed783ceb..9b0c64c28bff 100644 --- a/arch/arm/include/asm/efi.h +++ b/arch/arm/include/asm/efi.h @@ -52,7 +52,7 @@ void efi_virtmap_unload(void); #define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__) #define efi_call_runtime(f, ...) sys_table_arg->runtime->f(__VA_ARGS__) -#define efi_is_64bit() (false) +#define efi_is_native() (true) #define efi_table_attr(table, attr, instance) \ ((table##_t *)instance)->attr diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index 7cfac5e0e310..189082c44c28 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -95,7 +95,7 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base, #define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__) #define efi_call_runtime(f, ...) sys_table_arg->runtime->f(__VA_ARGS__) -#define efi_is_64bit() (true) +#define efi_is_native() (true) #define efi_table_attr(table, attr, instance) \ ((table##_t *)instance)->attr diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 959bcdd8c1fe..990b93379965 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -63,8 +63,7 @@ preserve_pci_rom_image(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom) * large romsize. The UEFI spec limits the size of option ROMs to 16 * MiB so we reject any ROMs over 16 MiB in size to catch this. */ - romimage = (void *)(unsigned long)efi_table_attr(efi_pci_io_protocol, - romimage, pci); + romimage = efi_table_attr(efi_pci_io_protocol, romimage, pci); romsize = efi_table_attr(efi_pci_io_protocol, romsize, pci); if (!romimage || !romsize || romsize > SZ_16M) return EFI_INVALID_PARAMETER; diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 6094e7f49a99..c27323cb49e5 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -222,21 +222,42 @@ static inline bool efi_is_64bit(void) return __efi_early()->is64; } -#define efi_table_attr(table, attr, instance) \ - (efi_is_64bit() ? \ - ((table##_64_t *)(unsigned long)instance)->attr : \ - ((table##_32_t *)(unsigned long)instance)->attr) +static inline bool efi_is_native(void) +{ + if (!IS_ENABLED(CONFIG_X86_64)) + return true; + 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(table, attr, instance) ({ \ + __typeof__(((table##_t *)0)->attr) __ret; \ + if (efi_is_native()) { \ + __ret = ((table##_t *)(unsigned long)instance)->attr; \ + } else { \ + __ret = (__typeof__(__ret))efi_mixed_mode_cast( \ + ((table##_t *)(unsigned long)instance)->mixed_mode.attr);\ + } \ + __ret; \ +}) #define efi_call_proto(protocol, f, instance, ...) \ - __efi_early()->call(efi_table_attr(protocol, f, instance), \ + __efi_early()->call((unsigned long) \ + efi_table_attr(protocol, f, instance), \ instance, ##__VA_ARGS__) #define efi_call_early(f, ...) \ - __efi_early()->call(efi_table_attr(efi_boot_services, f, \ + __efi_early()->call((unsigned long) \ + efi_table_attr(efi_boot_services, f, \ __efi_early()->boot_services), __VA_ARGS__) #define efi_call_runtime(f, ...) \ - __efi_early()->call(efi_table_attr(efi_runtime_services, f, \ + __efi_early()->call((unsigned long) \ + efi_table_attr(efi_runtime_services, f, \ __efi_early()->runtime_services), __VA_ARGS__) extern bool efi_reboot_required(void); |