LCOV - code coverage report
Current view: top level - arch/x86/include/asm - efi.h (source / functions) Hit Total Coverage
Test: landlock.info Lines: 4 4 100.0 %
Date: 2021-04-22 12:43:58 Functions: 0 0 -

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0 */
       2             : #ifndef _ASM_X86_EFI_H
       3             : #define _ASM_X86_EFI_H
       4             : 
       5             : #include <asm/fpu/api.h>
       6             : #include <asm/processor-flags.h>
       7             : #include <asm/tlb.h>
       8             : #include <asm/nospec-branch.h>
       9             : #include <asm/mmu_context.h>
      10             : #include <linux/build_bug.h>
      11             : #include <linux/kernel.h>
      12             : #include <linux/pgtable.h>
      13             : 
      14             : extern unsigned long efi_fw_vendor, efi_config_table;
      15             : extern unsigned long efi_mixed_mode_stack_pa;
      16             : 
      17             : /*
      18             :  * We map the EFI regions needed for runtime services non-contiguously,
      19             :  * with preserved alignment on virtual addresses starting from -4G down
      20             :  * for a total max space of 64G. This way, we provide for stable runtime
      21             :  * services addresses across kernels so that a kexec'd kernel can still
      22             :  * use them.
      23             :  *
      24             :  * This is the main reason why we're doing stable VA mappings for RT
      25             :  * services.
      26             :  */
      27             : 
      28             : #define EFI32_LOADER_SIGNATURE  "EL32"
      29             : #define EFI64_LOADER_SIGNATURE  "EL64"
      30             : 
      31             : #define ARCH_EFI_IRQ_FLAGS_MASK X86_EFLAGS_IF
      32             : 
      33             : /*
      34             :  * The EFI services are called through variadic functions in many cases. These
      35             :  * functions are implemented in assembler and support only a fixed number of
      36             :  * arguments. The macros below allows us to check at build time that we don't
      37             :  * try to call them with too many arguments.
      38             :  *
      39             :  * __efi_nargs() will return the number of arguments if it is 7 or less, and
      40             :  * cause a BUILD_BUG otherwise. The limitations of the C preprocessor make it
      41             :  * impossible to calculate the exact number of arguments beyond some
      42             :  * pre-defined limit. The maximum number of arguments currently supported by
      43             :  * any of the thunks is 7, so this is good enough for now and can be extended
      44             :  * in the obvious way if we ever need more.
      45             :  */
      46             : 
      47             : #define __efi_nargs(...) __efi_nargs_(__VA_ARGS__)
      48             : #define __efi_nargs_(...) __efi_nargs__(0, ##__VA_ARGS__,       \
      49             :         __efi_arg_sentinel(7), __efi_arg_sentinel(6),           \
      50             :         __efi_arg_sentinel(5), __efi_arg_sentinel(4),           \
      51             :         __efi_arg_sentinel(3), __efi_arg_sentinel(2),           \
      52             :         __efi_arg_sentinel(1), __efi_arg_sentinel(0))
      53             : #define __efi_nargs__(_0, _1, _2, _3, _4, _5, _6, _7, n, ...)   \
      54             :         __take_second_arg(n,                                    \
      55             :                 ({ BUILD_BUG_ON_MSG(1, "__efi_nargs limit exceeded"); 8; }))
      56             : #define __efi_arg_sentinel(n) , n
      57             : 
      58             : /*
      59             :  * __efi_nargs_check(f, n, ...) will cause a BUILD_BUG if the ellipsis
      60             :  * represents more than n arguments.
      61             :  */
      62             : 
      63             : #define __efi_nargs_check(f, n, ...)                                    \
      64             :         __efi_nargs_check_(f, __efi_nargs(__VA_ARGS__), n)
      65             : #define __efi_nargs_check_(f, p, n) __efi_nargs_check__(f, p, n)
      66             : #define __efi_nargs_check__(f, p, n) ({                                 \
      67             :         BUILD_BUG_ON_MSG(                                               \
      68             :                 (p) > (n),                                           \
      69             :                 #f " called with too many arguments (" #p ">" #n ")"); \
      70             : })
      71             : 
      72             : static inline void efi_fpu_begin(void)
      73             : {
      74             :         /*
      75             :          * The UEFI calling convention (UEFI spec 2.3.2 and 2.3.4) requires
      76             :          * that FCW and MXCSR (64-bit) must be initialized prior to calling
      77             :          * UEFI code.  (Oddly the spec does not require that the FPU stack
      78             :          * be empty.)
      79             :          */
      80             :         kernel_fpu_begin_mask(KFPU_387 | KFPU_MXCSR);
      81             : }
      82             : 
      83             : static inline void efi_fpu_end(void)
      84             : {
      85             :         kernel_fpu_end();
      86             : }
      87             : 
      88             : #ifdef CONFIG_X86_32
      89             : #define arch_efi_call_virt_setup()                                      \
      90             : ({                                                                      \
      91             :         efi_fpu_begin();                                                \
      92             :         firmware_restrict_branch_speculation_start();                   \
      93             : })
      94             : 
      95             : #define arch_efi_call_virt_teardown()                                   \
      96             : ({                                                                      \
      97             :         firmware_restrict_branch_speculation_end();                     \
      98             :         efi_fpu_end();                                                  \
      99             : })
     100             : 
     101             : #define arch_efi_call_virt(p, f, args...)       p->f(args)
     102             : 
     103             : #else /* !CONFIG_X86_32 */
     104             : 
     105             : #define EFI_LOADER_SIGNATURE    "EL64"
     106             : 
     107             : extern asmlinkage u64 __efi_call(void *fp, ...);
     108             : 
     109             : #define efi_call(...) ({                                                \
     110             :         __efi_nargs_check(efi_call, 7, __VA_ARGS__);                    \
     111             :         __efi_call(__VA_ARGS__);                                        \
     112             : })
     113             : 
     114             : #define arch_efi_call_virt_setup()                                      \
     115             : ({                                                                      \
     116             :         efi_sync_low_kernel_mappings();                                 \
     117             :         efi_fpu_begin();                                                \
     118             :         firmware_restrict_branch_speculation_start();                   \
     119             :         efi_enter_mm();                                                 \
     120             : })
     121             : 
     122             : #define arch_efi_call_virt(p, f, args...)                               \
     123             :         efi_call((void *)p->f, args)                                 \
     124             : 
     125             : #define arch_efi_call_virt_teardown()                                   \
     126             : ({                                                                      \
     127             :         efi_leave_mm();                                                 \
     128             :         firmware_restrict_branch_speculation_end();                     \
     129             :         efi_fpu_end();                                                  \
     130             : })
     131             : 
     132             : #ifdef CONFIG_KASAN
     133             : /*
     134             :  * CONFIG_KASAN may redefine memset to __memset.  __memset function is present
     135             :  * only in kernel binary.  Since the EFI stub linked into a separate binary it
     136             :  * doesn't have __memset().  So we should use standard memset from
     137             :  * arch/x86/boot/compressed/string.c.  The same applies to memcpy and memmove.
     138             :  */
     139             : #undef memcpy
     140             : #undef memset
     141             : #undef memmove
     142             : #endif
     143             : 
     144             : #endif /* CONFIG_X86_32 */
     145             : 
     146             : extern int __init efi_memblock_x86_reserve_range(void);
     147             : extern void __init efi_print_memmap(void);
     148             : extern void __init efi_map_region(efi_memory_desc_t *md);
     149             : extern void __init efi_map_region_fixed(efi_memory_desc_t *md);
     150             : extern void efi_sync_low_kernel_mappings(void);
     151             : extern int __init efi_alloc_page_tables(void);
     152             : extern int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages);
     153             : extern void __init efi_runtime_update_mappings(void);
     154             : extern void __init efi_dump_pagetable(void);
     155             : extern void __init efi_apply_memmap_quirks(void);
     156             : extern int __init efi_reuse_config(u64 tables, int nr_tables);
     157             : extern void efi_delete_dummy_variable(void);
     158             : extern void efi_crash_gracefully_on_page_fault(unsigned long phys_addr);
     159             : extern void efi_free_boot_services(void);
     160             : 
     161             : void efi_enter_mm(void);
     162             : void efi_leave_mm(void);
     163             : 
     164             : /* kexec external ABI */
     165             : struct efi_setup_data {
     166             :         u64 fw_vendor;
     167             :         u64 __unused;
     168             :         u64 tables;
     169             :         u64 smbios;
     170             :         u64 reserved[8];
     171             : };
     172             : 
     173             : extern u64 efi_setup;
     174             : 
     175             : #ifdef CONFIG_EFI
     176             : extern efi_status_t __efi64_thunk(u32, ...);
     177             : 
     178             : #define efi64_thunk(...) ({                                             \
     179             :         __efi_nargs_check(efi64_thunk, 6, __VA_ARGS__);                 \
     180             :         __efi64_thunk(__VA_ARGS__);                                     \
     181             : })
     182             : 
     183             : static inline bool efi_is_mixed(void)
     184             : {
     185             :         if (!IS_ENABLED(CONFIG_EFI_MIXED))
     186             :                 return false;
     187             :         return IS_ENABLED(CONFIG_X86_64) && !efi_enabled(EFI_64BIT);
     188             : }
     189             : 
     190             : static inline bool efi_runtime_supported(void)
     191             : {
     192             :         if (IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT))
     193             :                 return true;
     194             : 
     195             :         return IS_ENABLED(CONFIG_EFI_MIXED);
     196             : }
     197             : 
     198             : extern void parse_efi_setup(u64 phys_addr, u32 data_len);
     199             : 
     200             : extern void efifb_setup_from_dmi(struct screen_info *si, const char *opt);
     201             : 
     202             : extern void efi_thunk_runtime_setup(void);
     203             : efi_status_t efi_set_virtual_address_map(unsigned long memory_map_size,
     204             :                                          unsigned long descriptor_size,
     205             :                                          u32 descriptor_version,
     206             :                                          efi_memory_desc_t *virtual_map,
     207             :                                          unsigned long systab_phys);
     208             : 
     209             : /* arch specific definitions used by the stub code */
     210             : 
     211             : #ifdef CONFIG_EFI_MIXED
     212             : 
     213             : #define ARCH_HAS_EFISTUB_WRAPPERS
     214             : 
     215             : static inline bool efi_is_64bit(void)
     216             : {
     217             :         extern const bool efi_is64;
     218             : 
     219             :         return efi_is64;
     220             : }
     221             : 
     222             : static inline bool efi_is_native(void)
     223             : {
     224             :         return efi_is_64bit();
     225             : }
     226             : 
     227             : #define efi_mixed_mode_cast(attr)                                       \
     228             :         __builtin_choose_expr(                                          \
     229             :                 __builtin_types_compatible_p(u32, __typeof__(attr)),    \
     230             :                         (unsigned long)(attr), (attr))
     231             : 
     232             : #define efi_table_attr(inst, attr)                                      \
     233             :         (efi_is_native()                                                \
     234             :                 ? inst->attr                                         \
     235             :                 : (__typeof__(inst->attr))                           \
     236             :                         efi_mixed_mode_cast(inst->mixed_mode.attr))
     237             : 
     238             : /*
     239             :  * The following macros allow translating arguments if necessary from native to
     240             :  * mixed mode. The use case for this is to initialize the upper 32 bits of
     241             :  * output parameters, and where the 32-bit method requires a 64-bit argument,
     242             :  * which must be split up into two arguments to be thunked properly.
     243             :  *
     244             :  * As examples, the AllocatePool boot service returns the address of the
     245             :  * allocation, but it will not set the high 32 bits of the address. To ensure
     246             :  * that the full 64-bit address is initialized, we zero-init the address before
     247             :  * calling the thunk.
     248             :  *
     249             :  * The FreePages boot service takes a 64-bit physical address even in 32-bit
     250             :  * mode. For the thunk to work correctly, a native 64-bit call of
     251             :  *      free_pages(addr, size)
     252             :  * must be translated to
     253             :  *      efi64_thunk(free_pages, addr & U32_MAX, addr >> 32, size)
     254             :  * so that the two 32-bit halves of addr get pushed onto the stack separately.
     255             :  */
     256             : 
     257             : static inline void *efi64_zero_upper(void *p)
     258             : {
     259             :         ((u32 *)p)[1] = 0;
     260             :         return p;
     261             : }
     262             : 
     263             : static inline u32 efi64_convert_status(efi_status_t status)
     264             : {
     265             :         return (u32)(status | (u64)status >> 32);
     266             : }
     267             : 
     268             : #define __efi64_argmap_free_pages(addr, size)                           \
     269             :         ((addr), 0, (size))
     270             : 
     271             : #define __efi64_argmap_get_memory_map(mm_size, mm, key, size, ver)      \
     272             :         ((mm_size), (mm), efi64_zero_upper(key), efi64_zero_upper(size), (ver))
     273             : 
     274             : #define __efi64_argmap_allocate_pool(type, size, buffer)                \
     275             :         ((type), (size), efi64_zero_upper(buffer))
     276             : 
     277             : #define __efi64_argmap_create_event(type, tpl, f, c, event)             \
     278             :         ((type), (tpl), (f), (c), efi64_zero_upper(event))
     279             : 
     280             : #define __efi64_argmap_set_timer(event, type, time)                     \
     281             :         ((event), (type), lower_32_bits(time), upper_32_bits(time))
     282             : 
     283             : #define __efi64_argmap_wait_for_event(num, event, index)                \
     284             :         ((num), (event), efi64_zero_upper(index))
     285             : 
     286             : #define __efi64_argmap_handle_protocol(handle, protocol, interface)     \
     287             :         ((handle), (protocol), efi64_zero_upper(interface))
     288             : 
     289             : #define __efi64_argmap_locate_protocol(protocol, reg, interface)        \
     290             :         ((protocol), (reg), efi64_zero_upper(interface))
     291             : 
     292             : #define __efi64_argmap_locate_device_path(protocol, path, handle)       \
     293             :         ((protocol), (path), efi64_zero_upper(handle))
     294             : 
     295             : #define __efi64_argmap_exit(handle, status, size, data)                 \
     296             :         ((handle), efi64_convert_status(status), (size), (data))
     297             : 
     298             : /* PCI I/O */
     299             : #define __efi64_argmap_get_location(protocol, seg, bus, dev, func)      \
     300             :         ((protocol), efi64_zero_upper(seg), efi64_zero_upper(bus),      \
     301             :          efi64_zero_upper(dev), efi64_zero_upper(func))
     302             : 
     303             : /* LoadFile */
     304             : #define __efi64_argmap_load_file(protocol, path, policy, bufsize, buf)  \
     305             :         ((protocol), (path), (policy), efi64_zero_upper(bufsize), (buf))
     306             : 
     307             : /* Graphics Output Protocol */
     308             : #define __efi64_argmap_query_mode(gop, mode, size, info)                \
     309             :         ((gop), (mode), efi64_zero_upper(size), efi64_zero_upper(info))
     310             : 
     311             : /*
     312             :  * The macros below handle the plumbing for the argument mapping. To add a
     313             :  * mapping for a specific EFI method, simply define a macro
     314             :  * __efi64_argmap_<method name>, following the examples above.
     315             :  */
     316             : 
     317             : #define __efi64_thunk_map(inst, func, ...)                              \
     318             :         efi64_thunk(inst->mixed_mode.func,                           \
     319             :                 __efi64_argmap(__efi64_argmap_ ## func(__VA_ARGS__),    \
     320             :                                (__VA_ARGS__)))
     321             : 
     322             : #define __efi64_argmap(mapped, args)                                    \
     323             :         __PASTE(__efi64_argmap__, __efi_nargs(__efi_eat mapped))(mapped, args)
     324             : #define __efi64_argmap__0(mapped, args) __efi_eval mapped
     325             : #define __efi64_argmap__1(mapped, args) __efi_eval args
     326             : 
     327             : #define __efi_eat(...)
     328             : #define __efi_eval(...) __VA_ARGS__
     329             : 
     330             : /* The three macros below handle dispatching via the thunk if needed */
     331             : 
     332             : #define efi_call_proto(inst, func, ...)                                 \
     333             :         (efi_is_native()                                                \
     334             :                 ? inst->func(inst, ##__VA_ARGS__)                    \
     335             :                 : __efi64_thunk_map(inst, func, inst, ##__VA_ARGS__))
     336             : 
     337             : #define efi_bs_call(func, ...)                                          \
     338             :         (efi_is_native()                                                \
     339             :                 ? efi_system_table->boottime->func(__VA_ARGS__)           \
     340             :                 : __efi64_thunk_map(efi_table_attr(efi_system_table,    \
     341             :                                                    boottime),           \
     342             :                                     func, __VA_ARGS__))
     343             : 
     344             : #define efi_rt_call(func, ...)                                          \
     345             :         (efi_is_native()                                                \
     346             :                 ? efi_system_table->runtime->func(__VA_ARGS__)            \
     347             :                 : __efi64_thunk_map(efi_table_attr(efi_system_table,    \
     348             :                                                    runtime),            \
     349             :                                     func, __VA_ARGS__))
     350             : 
     351             : #else /* CONFIG_EFI_MIXED */
     352             : 
     353             : static inline bool efi_is_64bit(void)
     354             : {
     355             :         return IS_ENABLED(CONFIG_X86_64);
     356             : }
     357             : 
     358             : #endif /* CONFIG_EFI_MIXED */
     359             : 
     360             : extern bool efi_reboot_required(void);
     361             : extern bool efi_is_table_address(unsigned long phys_addr);
     362             : 
     363             : extern void efi_find_mirror(void);
     364             : extern void efi_reserve_boot_services(void);
     365             : #else
     366             : static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {}
     367             : static inline bool efi_reboot_required(void)
     368             : {
     369             :         return false;
     370             : }
     371             : static inline  bool efi_is_table_address(unsigned long phys_addr)
     372             : {
     373             :         return false;
     374             : }
     375           1 : static inline void efi_find_mirror(void)
     376             : {
     377           1 : }
     378           1 : static inline void efi_reserve_boot_services(void)
     379             : {
     380           1 : }
     381             : #endif /* CONFIG_EFI */
     382             : 
     383             : #ifdef CONFIG_EFI_FAKE_MEMMAP
     384             : extern void __init efi_fake_memmap_early(void);
     385             : #else
     386             : static inline void efi_fake_memmap_early(void)
     387             : {
     388             : }
     389             : #endif
     390             : 
     391             : #define arch_ima_efi_boot_mode  \
     392             :         ({ extern struct boot_params boot_params; boot_params.secure_boot; })
     393             : 
     394             : #endif /* _ASM_X86_EFI_H */

Generated by: LCOV version 1.14