/* * We map the EFI regions needed for runtime services non-contiguously, * with preserved alignment on virtual addresses starting from -4G down * for a total max space of 64G. This way, we provide for stable runtime * services addresses across kernels so that a kexec'd kernel can still * use them. * * This is the main reason why we're doing stable VA mappings for RT * services.
*/
/* * The EFI services are called through variadic functions in many cases. These * functions are implemented in assembler and support only a fixed number of * arguments. The macros below allows us to check at build time that we don't * try to call them with too many arguments. * * __efi_nargs() will return the number of arguments if it is 7 or less, and * cause a BUILD_BUG otherwise. The limitations of the C preprocessor make it * impossible to calculate the exact number of arguments beyond some * pre-defined limit. The maximum number of arguments currently supported by * any of the thunks is 7, so this is good enough for now and can be extended * in the obvious way if we ever need more.
*/
/* * __efi_nargs_check(f, n, ...) will cause a BUILD_BUG if the ellipsis * represents more than n arguments.
*/
#define __efi_nargs_check(f, n, ...) \
__efi_nargs_check_(f, __efi_nargs(__VA_ARGS__), n) #define __efi_nargs_check_(f, p, n) __efi_nargs_check__(f, p, n) #define __efi_nargs_check__(f, p, n) ({ \
BUILD_BUG_ON_MSG( \
(p) > (n), \ #f" called with too many arguments ("#p">"#n")"); \
})
staticinlinevoid efi_fpu_begin(void)
{ /* * The UEFI calling convention (UEFI spec 2.3.2 and 2.3.4) requires * that FCW and MXCSR (64-bit) must be initialized prior to calling * UEFI code. (Oddly the spec does not require that the FPU stack * be empty.)
*/
kernel_fpu_begin_mask(KFPU_387 | KFPU_MXCSR);
}
#ifdef CONFIG_KASAN /* * CONFIG_KASAN may redefine memset to __memset. __memset function is present * only in kernel binary. Since the EFI stub linked into a separate binary it * doesn't have __memset(). So we should use standard memset from * arch/x86/boot/compressed/string.c. The same applies to memcpy and memmove.
*/ #undef memcpy #undef memset #undef memmove #endif
#define efi64_thunk(...) ({ \
u64 __pad[3]; /* must have space for 3 args on the stack */ \
__efi_nargs_check(efi64_thunk, 9, __VA_ARGS__); \
__efi64_thunk(__VA_ARGS__, __pad); \
})
/* * The following macros allow translating arguments if necessary from native to * mixed mode. The use case for this is to initialize the upper 32 bits of * output parameters, and where the 32-bit method requires a 64-bit argument, * which must be split up into two arguments to be thunked properly. * * As examples, the AllocatePool boot service returns the address of the * allocation, but it will not set the high 32 bits of the address. To ensure * that the full 64-bit address is initialized, we zero-init the address before * calling the thunk. * * The FreePages boot service takes a 64-bit physical address even in 32-bit * mode. For the thunk to work correctly, a native 64-bit call of * free_pages(addr, size) * must be translated to * efi64_thunk(free_pages, addr & U32_MAX, addr >> 32, size) * so that the two 32-bit halves of addr get pushed onto the stack separately.
*/
/* EFI SMBIOS protocol */ #define __efi64_argmap_get_next(protocol, smbioshandle, type, record, phandle) \
((protocol), (smbioshandle), (type), efi64_zero_upper(record), \
efi64_zero_upper(phandle)) /* * The macros below handle the plumbing for the argument mapping. To add a * mapping for a specific EFI method, simply define a macro * __efi64_argmap_<method name>, following the examples above.
*/
staticinline 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 */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.