Merge branch 'x86/kdump' into locking/kcsan, to resolve conflicts
Conflicts: arch/x86/purgatory/Makefile Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
@@ -41,7 +41,7 @@ OBJECT_FILES_NON_STANDARD := y
|
||||
KCOV_INSTRUMENT := n
|
||||
|
||||
lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o \
|
||||
random.o
|
||||
random.o pci.o
|
||||
|
||||
# include the stub's generic dependencies from lib/ when building for ARM/arm64
|
||||
arm-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c
|
||||
|
@@ -37,16 +37,14 @@
|
||||
|
||||
static u64 virtmap_base = EFI_RT_VIRTUAL_BASE;
|
||||
|
||||
void efi_char16_printk(efi_system_table_t *sys_table_arg,
|
||||
efi_char16_t *str)
|
||||
{
|
||||
struct efi_simple_text_output_protocol *out;
|
||||
static efi_system_table_t *__efistub_global sys_table;
|
||||
|
||||
out = (struct efi_simple_text_output_protocol *)sys_table_arg->con_out;
|
||||
out->output_string(out, str);
|
||||
__pure efi_system_table_t *efi_system_table(void)
|
||||
{
|
||||
return sys_table;
|
||||
}
|
||||
|
||||
static struct screen_info *setup_graphics(efi_system_table_t *sys_table_arg)
|
||||
static struct screen_info *setup_graphics(void)
|
||||
{
|
||||
efi_guid_t gop_proto = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
||||
efi_status_t status;
|
||||
@@ -55,27 +53,27 @@ static struct screen_info *setup_graphics(efi_system_table_t *sys_table_arg)
|
||||
struct screen_info *si = NULL;
|
||||
|
||||
size = 0;
|
||||
status = efi_call_early(locate_handle, EFI_LOCATE_BY_PROTOCOL,
|
||||
&gop_proto, NULL, &size, gop_handle);
|
||||
status = efi_bs_call(locate_handle, EFI_LOCATE_BY_PROTOCOL,
|
||||
&gop_proto, NULL, &size, gop_handle);
|
||||
if (status == EFI_BUFFER_TOO_SMALL) {
|
||||
si = alloc_screen_info(sys_table_arg);
|
||||
si = alloc_screen_info();
|
||||
if (!si)
|
||||
return NULL;
|
||||
efi_setup_gop(sys_table_arg, si, &gop_proto, size);
|
||||
efi_setup_gop(si, &gop_proto, size);
|
||||
}
|
||||
return si;
|
||||
}
|
||||
|
||||
void install_memreserve_table(efi_system_table_t *sys_table_arg)
|
||||
void install_memreserve_table(void)
|
||||
{
|
||||
struct linux_efi_memreserve *rsv;
|
||||
efi_guid_t memreserve_table_guid = LINUX_EFI_MEMRESERVE_TABLE_GUID;
|
||||
efi_status_t status;
|
||||
|
||||
status = efi_call_early(allocate_pool, EFI_LOADER_DATA, sizeof(*rsv),
|
||||
(void **)&rsv);
|
||||
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, sizeof(*rsv),
|
||||
(void **)&rsv);
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table_arg, "Failed to allocate memreserve entry!\n");
|
||||
pr_efi_err("Failed to allocate memreserve entry!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -83,11 +81,10 @@ void install_memreserve_table(efi_system_table_t *sys_table_arg)
|
||||
rsv->size = 0;
|
||||
atomic_set(&rsv->count, 0);
|
||||
|
||||
status = efi_call_early(install_configuration_table,
|
||||
&memreserve_table_guid,
|
||||
rsv);
|
||||
status = efi_bs_call(install_configuration_table,
|
||||
&memreserve_table_guid, rsv);
|
||||
if (status != EFI_SUCCESS)
|
||||
pr_efi_err(sys_table_arg, "Failed to install memreserve config table!\n");
|
||||
pr_efi_err("Failed to install memreserve config table!\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -97,8 +94,7 @@ void install_memreserve_table(efi_system_table_t *sys_table_arg)
|
||||
* must be reserved. On failure it is required to free all
|
||||
* all allocations it has made.
|
||||
*/
|
||||
efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
|
||||
unsigned long *image_addr,
|
||||
efi_status_t handle_kernel_image(unsigned long *image_addr,
|
||||
unsigned long *image_size,
|
||||
unsigned long *reserve_addr,
|
||||
unsigned long *reserve_size,
|
||||
@@ -110,7 +106,7 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
|
||||
* for both archictectures, with the arch-specific code provided in the
|
||||
* handle_kernel_image() function.
|
||||
*/
|
||||
unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
|
||||
unsigned long efi_entry(void *handle, efi_system_table_t *sys_table_arg,
|
||||
unsigned long *image_addr)
|
||||
{
|
||||
efi_loaded_image_t *image;
|
||||
@@ -131,11 +127,13 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
|
||||
enum efi_secureboot_mode secure_boot;
|
||||
struct screen_info *si;
|
||||
|
||||
sys_table = sys_table_arg;
|
||||
|
||||
/* Check if we were booted by the EFI firmware */
|
||||
if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
|
||||
goto fail;
|
||||
|
||||
status = check_platform_features(sys_table);
|
||||
status = check_platform_features();
|
||||
if (status != EFI_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
@@ -147,13 +145,13 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
|
||||
status = sys_table->boottime->handle_protocol(handle,
|
||||
&loaded_image_proto, (void *)&image);
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table, "Failed to get loaded image protocol\n");
|
||||
pr_efi_err("Failed to get loaded image protocol\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dram_base = get_dram_base(sys_table);
|
||||
dram_base = get_dram_base();
|
||||
if (dram_base == EFI_ERROR) {
|
||||
pr_efi_err(sys_table, "Failed to find DRAM base\n");
|
||||
pr_efi_err("Failed to find DRAM base\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -162,9 +160,9 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
|
||||
* protocol. We are going to copy the command line into the
|
||||
* device tree, so this can be allocated anywhere.
|
||||
*/
|
||||
cmdline_ptr = efi_convert_cmdline(sys_table, image, &cmdline_size);
|
||||
cmdline_ptr = efi_convert_cmdline(image, &cmdline_size);
|
||||
if (!cmdline_ptr) {
|
||||
pr_efi_err(sys_table, "getting command line via LOADED_IMAGE_PROTOCOL\n");
|
||||
pr_efi_err("getting command line via LOADED_IMAGE_PROTOCOL\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -176,25 +174,25 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
|
||||
if (!IS_ENABLED(CONFIG_CMDLINE_FORCE) && cmdline_size > 0)
|
||||
efi_parse_options(cmdline_ptr);
|
||||
|
||||
pr_efi(sys_table, "Booting Linux Kernel...\n");
|
||||
pr_efi("Booting Linux Kernel...\n");
|
||||
|
||||
si = setup_graphics(sys_table);
|
||||
si = setup_graphics();
|
||||
|
||||
status = handle_kernel_image(sys_table, image_addr, &image_size,
|
||||
status = handle_kernel_image(image_addr, &image_size,
|
||||
&reserve_addr,
|
||||
&reserve_size,
|
||||
dram_base, image);
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table, "Failed to relocate kernel\n");
|
||||
pr_efi_err("Failed to relocate kernel\n");
|
||||
goto fail_free_cmdline;
|
||||
}
|
||||
|
||||
efi_retrieve_tpm2_eventlog(sys_table);
|
||||
efi_retrieve_tpm2_eventlog();
|
||||
|
||||
/* Ask the firmware to clear memory on unclean shutdown */
|
||||
efi_enable_reset_attack_mitigation(sys_table);
|
||||
efi_enable_reset_attack_mitigation();
|
||||
|
||||
secure_boot = efi_get_secureboot(sys_table);
|
||||
secure_boot = efi_get_secureboot();
|
||||
|
||||
/*
|
||||
* Unauthenticated device tree data is a security hazard, so ignore
|
||||
@@ -204,39 +202,38 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
|
||||
if (!IS_ENABLED(CONFIG_EFI_ARMSTUB_DTB_LOADER) ||
|
||||
secure_boot != efi_secureboot_mode_disabled) {
|
||||
if (strstr(cmdline_ptr, "dtb="))
|
||||
pr_efi(sys_table, "Ignoring DTB from command line.\n");
|
||||
pr_efi("Ignoring DTB from command line.\n");
|
||||
} else {
|
||||
status = handle_cmdline_files(sys_table, image, cmdline_ptr,
|
||||
"dtb=",
|
||||
status = handle_cmdline_files(image, cmdline_ptr, "dtb=",
|
||||
~0UL, &fdt_addr, &fdt_size);
|
||||
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table, "Failed to load device tree!\n");
|
||||
pr_efi_err("Failed to load device tree!\n");
|
||||
goto fail_free_image;
|
||||
}
|
||||
}
|
||||
|
||||
if (fdt_addr) {
|
||||
pr_efi(sys_table, "Using DTB from command line\n");
|
||||
pr_efi("Using DTB from command line\n");
|
||||
} else {
|
||||
/* Look for a device tree configuration table entry. */
|
||||
fdt_addr = (uintptr_t)get_fdt(sys_table, &fdt_size);
|
||||
fdt_addr = (uintptr_t)get_fdt(&fdt_size);
|
||||
if (fdt_addr)
|
||||
pr_efi(sys_table, "Using DTB from configuration table\n");
|
||||
pr_efi("Using DTB from configuration table\n");
|
||||
}
|
||||
|
||||
if (!fdt_addr)
|
||||
pr_efi(sys_table, "Generating empty DTB\n");
|
||||
pr_efi("Generating empty DTB\n");
|
||||
|
||||
status = handle_cmdline_files(sys_table, image, cmdline_ptr, "initrd=",
|
||||
status = handle_cmdline_files(image, cmdline_ptr, "initrd=",
|
||||
efi_get_max_initrd_addr(dram_base,
|
||||
*image_addr),
|
||||
(unsigned long *)&initrd_addr,
|
||||
(unsigned long *)&initrd_size);
|
||||
if (status != EFI_SUCCESS)
|
||||
pr_efi_err(sys_table, "Failed initrd from command line!\n");
|
||||
pr_efi_err("Failed initrd from command line!\n");
|
||||
|
||||
efi_random_get_seed(sys_table);
|
||||
efi_random_get_seed();
|
||||
|
||||
/* hibernation expects the runtime regions to stay in the same place */
|
||||
if (!IS_ENABLED(CONFIG_HIBERNATION) && !nokaslr()) {
|
||||
@@ -251,18 +248,17 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
|
||||
EFI_RT_VIRTUAL_SIZE;
|
||||
u32 rnd;
|
||||
|
||||
status = efi_get_random_bytes(sys_table, sizeof(rnd),
|
||||
(u8 *)&rnd);
|
||||
status = efi_get_random_bytes(sizeof(rnd), (u8 *)&rnd);
|
||||
if (status == EFI_SUCCESS) {
|
||||
virtmap_base = EFI_RT_VIRTUAL_BASE +
|
||||
(((headroom >> 21) * rnd) >> (32 - 21));
|
||||
}
|
||||
}
|
||||
|
||||
install_memreserve_table(sys_table);
|
||||
install_memreserve_table();
|
||||
|
||||
new_fdt_addr = fdt_addr;
|
||||
status = allocate_new_fdt_and_exit_boot(sys_table, handle,
|
||||
status = allocate_new_fdt_and_exit_boot(handle,
|
||||
&new_fdt_addr, efi_get_max_fdt_addr(dram_base),
|
||||
initrd_addr, initrd_size, cmdline_ptr,
|
||||
fdt_addr, fdt_size);
|
||||
@@ -275,17 +271,17 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
|
||||
if (status == EFI_SUCCESS)
|
||||
return new_fdt_addr;
|
||||
|
||||
pr_efi_err(sys_table, "Failed to update FDT and exit boot services\n");
|
||||
pr_efi_err("Failed to update FDT and exit boot services\n");
|
||||
|
||||
efi_free(sys_table, initrd_size, initrd_addr);
|
||||
efi_free(sys_table, fdt_size, fdt_addr);
|
||||
efi_free(initrd_size, initrd_addr);
|
||||
efi_free(fdt_size, fdt_addr);
|
||||
|
||||
fail_free_image:
|
||||
efi_free(sys_table, image_size, *image_addr);
|
||||
efi_free(sys_table, reserve_size, reserve_addr);
|
||||
efi_free(image_size, *image_addr);
|
||||
efi_free(reserve_size, reserve_addr);
|
||||
fail_free_cmdline:
|
||||
free_screen_info(sys_table, si);
|
||||
efi_free(sys_table, cmdline_size, (unsigned long)cmdline_ptr);
|
||||
free_screen_info(si);
|
||||
efi_free(cmdline_size, (unsigned long)cmdline_ptr);
|
||||
fail:
|
||||
return EFI_ERROR;
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "efistub.h"
|
||||
|
||||
efi_status_t check_platform_features(efi_system_table_t *sys_table_arg)
|
||||
efi_status_t check_platform_features(void)
|
||||
{
|
||||
int block;
|
||||
|
||||
@@ -18,7 +18,7 @@ efi_status_t check_platform_features(efi_system_table_t *sys_table_arg)
|
||||
/* LPAE kernels need compatible hardware */
|
||||
block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0);
|
||||
if (block < 5) {
|
||||
pr_efi_err(sys_table_arg, "This LPAE kernel is not supported by your CPU\n");
|
||||
pr_efi_err("This LPAE kernel is not supported by your CPU\n");
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
@@ -26,7 +26,7 @@ efi_status_t check_platform_features(efi_system_table_t *sys_table_arg)
|
||||
|
||||
static efi_guid_t screen_info_guid = LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID;
|
||||
|
||||
struct screen_info *alloc_screen_info(efi_system_table_t *sys_table_arg)
|
||||
struct screen_info *alloc_screen_info(void)
|
||||
{
|
||||
struct screen_info *si;
|
||||
efi_status_t status;
|
||||
@@ -37,32 +37,31 @@ struct screen_info *alloc_screen_info(efi_system_table_t *sys_table_arg)
|
||||
* its contents while we hand over to the kernel proper from the
|
||||
* decompressor.
|
||||
*/
|
||||
status = efi_call_early(allocate_pool, EFI_RUNTIME_SERVICES_DATA,
|
||||
sizeof(*si), (void **)&si);
|
||||
status = efi_bs_call(allocate_pool, EFI_RUNTIME_SERVICES_DATA,
|
||||
sizeof(*si), (void **)&si);
|
||||
|
||||
if (status != EFI_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
status = efi_call_early(install_configuration_table,
|
||||
&screen_info_guid, si);
|
||||
status = efi_bs_call(install_configuration_table,
|
||||
&screen_info_guid, si);
|
||||
if (status == EFI_SUCCESS)
|
||||
return si;
|
||||
|
||||
efi_call_early(free_pool, si);
|
||||
efi_bs_call(free_pool, si);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_screen_info(efi_system_table_t *sys_table_arg, struct screen_info *si)
|
||||
void free_screen_info(struct screen_info *si)
|
||||
{
|
||||
if (!si)
|
||||
return;
|
||||
|
||||
efi_call_early(install_configuration_table, &screen_info_guid, NULL);
|
||||
efi_call_early(free_pool, si);
|
||||
efi_bs_call(install_configuration_table, &screen_info_guid, NULL);
|
||||
efi_bs_call(free_pool, si);
|
||||
}
|
||||
|
||||
static efi_status_t reserve_kernel_base(efi_system_table_t *sys_table_arg,
|
||||
unsigned long dram_base,
|
||||
static efi_status_t reserve_kernel_base(unsigned long dram_base,
|
||||
unsigned long *reserve_addr,
|
||||
unsigned long *reserve_size)
|
||||
{
|
||||
@@ -92,8 +91,8 @@ static efi_status_t reserve_kernel_base(efi_system_table_t *sys_table_arg,
|
||||
*/
|
||||
alloc_addr = dram_base + MAX_UNCOMP_KERNEL_SIZE;
|
||||
nr_pages = MAX_UNCOMP_KERNEL_SIZE / EFI_PAGE_SIZE;
|
||||
status = efi_call_early(allocate_pages, EFI_ALLOCATE_MAX_ADDRESS,
|
||||
EFI_BOOT_SERVICES_DATA, nr_pages, &alloc_addr);
|
||||
status = efi_bs_call(allocate_pages, EFI_ALLOCATE_MAX_ADDRESS,
|
||||
EFI_BOOT_SERVICES_DATA, nr_pages, &alloc_addr);
|
||||
if (status == EFI_SUCCESS) {
|
||||
if (alloc_addr == dram_base) {
|
||||
*reserve_addr = alloc_addr;
|
||||
@@ -119,10 +118,9 @@ static efi_status_t reserve_kernel_base(efi_system_table_t *sys_table_arg,
|
||||
* released to the OS after ExitBootServices(), the decompressor can
|
||||
* safely overwrite them.
|
||||
*/
|
||||
status = efi_get_memory_map(sys_table_arg, &map);
|
||||
status = efi_get_memory_map(&map);
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table_arg,
|
||||
"reserve_kernel_base(): Unable to retrieve memory map.\n");
|
||||
pr_efi_err("reserve_kernel_base(): Unable to retrieve memory map.\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -158,14 +156,13 @@ static efi_status_t reserve_kernel_base(efi_system_table_t *sys_table_arg,
|
||||
start = max(start, (u64)dram_base);
|
||||
end = min(end, (u64)dram_base + MAX_UNCOMP_KERNEL_SIZE);
|
||||
|
||||
status = efi_call_early(allocate_pages,
|
||||
EFI_ALLOCATE_ADDRESS,
|
||||
EFI_LOADER_DATA,
|
||||
(end - start) / EFI_PAGE_SIZE,
|
||||
&start);
|
||||
status = efi_bs_call(allocate_pages,
|
||||
EFI_ALLOCATE_ADDRESS,
|
||||
EFI_LOADER_DATA,
|
||||
(end - start) / EFI_PAGE_SIZE,
|
||||
&start);
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table_arg,
|
||||
"reserve_kernel_base(): alloc failed.\n");
|
||||
pr_efi_err("reserve_kernel_base(): alloc failed.\n");
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
@@ -188,12 +185,11 @@ static efi_status_t reserve_kernel_base(efi_system_table_t *sys_table_arg,
|
||||
|
||||
status = EFI_SUCCESS;
|
||||
out:
|
||||
efi_call_early(free_pool, memory_map);
|
||||
efi_bs_call(free_pool, memory_map);
|
||||
return status;
|
||||
}
|
||||
|
||||
efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
|
||||
unsigned long *image_addr,
|
||||
efi_status_t handle_kernel_image(unsigned long *image_addr,
|
||||
unsigned long *image_size,
|
||||
unsigned long *reserve_addr,
|
||||
unsigned long *reserve_size,
|
||||
@@ -221,10 +217,9 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
|
||||
*/
|
||||
kernel_base += TEXT_OFFSET - 5 * PAGE_SIZE;
|
||||
|
||||
status = reserve_kernel_base(sys_table, kernel_base, reserve_addr,
|
||||
reserve_size);
|
||||
status = reserve_kernel_base(kernel_base, reserve_addr, reserve_size);
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table, "Unable to allocate memory for uncompressed kernel.\n");
|
||||
pr_efi_err("Unable to allocate memory for uncompressed kernel.\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -233,12 +228,11 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
|
||||
* memory window.
|
||||
*/
|
||||
*image_size = image->image_size;
|
||||
status = efi_relocate_kernel(sys_table, image_addr, *image_size,
|
||||
*image_size,
|
||||
status = efi_relocate_kernel(image_addr, *image_size, *image_size,
|
||||
kernel_base + MAX_UNCOMP_KERNEL_SIZE, 0, 0);
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table, "Failed to relocate kernel.\n");
|
||||
efi_free(sys_table, *reserve_size, *reserve_addr);
|
||||
pr_efi_err("Failed to relocate kernel.\n");
|
||||
efi_free(*reserve_size, *reserve_addr);
|
||||
*reserve_size = 0;
|
||||
return status;
|
||||
}
|
||||
@@ -249,10 +243,10 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
|
||||
* address at which the zImage is loaded.
|
||||
*/
|
||||
if (*image_addr + *image_size > dram_base + ZIMAGE_OFFSET_LIMIT) {
|
||||
pr_efi_err(sys_table, "Failed to relocate kernel, no low memory available.\n");
|
||||
efi_free(sys_table, *reserve_size, *reserve_addr);
|
||||
pr_efi_err("Failed to relocate kernel, no low memory available.\n");
|
||||
efi_free(*reserve_size, *reserve_addr);
|
||||
*reserve_size = 0;
|
||||
efi_free(sys_table, *image_size, *image_addr);
|
||||
efi_free(*image_size, *image_addr);
|
||||
*image_size = 0;
|
||||
return EFI_LOAD_ERROR;
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "efistub.h"
|
||||
|
||||
efi_status_t check_platform_features(efi_system_table_t *sys_table_arg)
|
||||
efi_status_t check_platform_features(void)
|
||||
{
|
||||
u64 tg;
|
||||
|
||||
@@ -32,16 +32,15 @@ efi_status_t check_platform_features(efi_system_table_t *sys_table_arg)
|
||||
tg = (read_cpuid(ID_AA64MMFR0_EL1) >> ID_AA64MMFR0_TGRAN_SHIFT) & 0xf;
|
||||
if (tg != ID_AA64MMFR0_TGRAN_SUPPORTED) {
|
||||
if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
|
||||
pr_efi_err(sys_table_arg, "This 64 KB granular kernel is not supported by your CPU\n");
|
||||
pr_efi_err("This 64 KB granular kernel is not supported by your CPU\n");
|
||||
else
|
||||
pr_efi_err(sys_table_arg, "This 16 KB granular kernel is not supported by your CPU\n");
|
||||
pr_efi_err("This 16 KB granular kernel is not supported by your CPU\n");
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg,
|
||||
unsigned long *image_addr,
|
||||
efi_status_t handle_kernel_image(unsigned long *image_addr,
|
||||
unsigned long *image_size,
|
||||
unsigned long *reserve_addr,
|
||||
unsigned long *reserve_size,
|
||||
@@ -56,17 +55,16 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg,
|
||||
|
||||
if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
|
||||
if (!nokaslr()) {
|
||||
status = efi_get_random_bytes(sys_table_arg,
|
||||
sizeof(phys_seed),
|
||||
status = efi_get_random_bytes(sizeof(phys_seed),
|
||||
(u8 *)&phys_seed);
|
||||
if (status == EFI_NOT_FOUND) {
|
||||
pr_efi(sys_table_arg, "EFI_RNG_PROTOCOL unavailable, no randomness supplied\n");
|
||||
pr_efi("EFI_RNG_PROTOCOL unavailable, no randomness supplied\n");
|
||||
} else if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table_arg, "efi_get_random_bytes() failed\n");
|
||||
pr_efi_err("efi_get_random_bytes() failed\n");
|
||||
return status;
|
||||
}
|
||||
} else {
|
||||
pr_efi(sys_table_arg, "KASLR disabled on kernel command line\n");
|
||||
pr_efi("KASLR disabled on kernel command line\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +106,7 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg,
|
||||
* locate the kernel at a randomized offset in physical memory.
|
||||
*/
|
||||
*reserve_size = kernel_memsize + offset;
|
||||
status = efi_random_alloc(sys_table_arg, *reserve_size,
|
||||
status = efi_random_alloc(*reserve_size,
|
||||
MIN_KIMG_ALIGN, reserve_addr,
|
||||
(u32)phys_seed);
|
||||
|
||||
@@ -131,19 +129,19 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg,
|
||||
*image_addr = *reserve_addr = preferred_offset;
|
||||
*reserve_size = round_up(kernel_memsize, EFI_ALLOC_ALIGN);
|
||||
|
||||
status = efi_call_early(allocate_pages, EFI_ALLOCATE_ADDRESS,
|
||||
EFI_LOADER_DATA,
|
||||
*reserve_size / EFI_PAGE_SIZE,
|
||||
(efi_physical_addr_t *)reserve_addr);
|
||||
status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS,
|
||||
EFI_LOADER_DATA,
|
||||
*reserve_size / EFI_PAGE_SIZE,
|
||||
(efi_physical_addr_t *)reserve_addr);
|
||||
}
|
||||
|
||||
if (status != EFI_SUCCESS) {
|
||||
*reserve_size = kernel_memsize + TEXT_OFFSET;
|
||||
status = efi_low_alloc(sys_table_arg, *reserve_size,
|
||||
status = efi_low_alloc(*reserve_size,
|
||||
MIN_KIMG_ALIGN, reserve_addr);
|
||||
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table_arg, "Failed to relocate kernel\n");
|
||||
pr_efi_err("Failed to relocate kernel\n");
|
||||
*reserve_size = 0;
|
||||
return status;
|
||||
}
|
||||
|
@@ -27,24 +27,26 @@
|
||||
*/
|
||||
#define EFI_READ_CHUNK_SIZE (1024 * 1024)
|
||||
|
||||
static unsigned long __chunk_size = EFI_READ_CHUNK_SIZE;
|
||||
static unsigned long efi_chunk_size = EFI_READ_CHUNK_SIZE;
|
||||
|
||||
static int __section(.data) __nokaslr;
|
||||
static int __section(.data) __quiet;
|
||||
static int __section(.data) __novamap;
|
||||
static bool __section(.data) efi_nosoftreserve;
|
||||
static bool __efistub_global efi_nokaslr;
|
||||
static bool __efistub_global efi_quiet;
|
||||
static bool __efistub_global efi_novamap;
|
||||
static bool __efistub_global efi_nosoftreserve;
|
||||
static bool __efistub_global efi_disable_pci_dma =
|
||||
IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA);
|
||||
|
||||
int __pure nokaslr(void)
|
||||
bool __pure nokaslr(void)
|
||||
{
|
||||
return __nokaslr;
|
||||
return efi_nokaslr;
|
||||
}
|
||||
int __pure is_quiet(void)
|
||||
bool __pure is_quiet(void)
|
||||
{
|
||||
return __quiet;
|
||||
return efi_quiet;
|
||||
}
|
||||
int __pure novamap(void)
|
||||
bool __pure novamap(void)
|
||||
{
|
||||
return __novamap;
|
||||
return efi_novamap;
|
||||
}
|
||||
bool __pure __efi_soft_reserve_enabled(void)
|
||||
{
|
||||
@@ -58,7 +60,7 @@ struct file_info {
|
||||
u64 size;
|
||||
};
|
||||
|
||||
void efi_printk(efi_system_table_t *sys_table_arg, char *str)
|
||||
void efi_printk(char *str)
|
||||
{
|
||||
char *s8;
|
||||
|
||||
@@ -68,10 +70,10 @@ void efi_printk(efi_system_table_t *sys_table_arg, char *str)
|
||||
ch[0] = *s8;
|
||||
if (*s8 == '\n') {
|
||||
efi_char16_t nl[2] = { '\r', 0 };
|
||||
efi_char16_printk(sys_table_arg, nl);
|
||||
efi_char16_printk(nl);
|
||||
}
|
||||
|
||||
efi_char16_printk(sys_table_arg, ch);
|
||||
efi_char16_printk(ch);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,8 +86,7 @@ static inline bool mmap_has_headroom(unsigned long buff_size,
|
||||
return slack / desc_size >= EFI_MMAP_NR_SLACK_SLOTS;
|
||||
}
|
||||
|
||||
efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg,
|
||||
struct efi_boot_memmap *map)
|
||||
efi_status_t efi_get_memory_map(struct efi_boot_memmap *map)
|
||||
{
|
||||
efi_memory_desc_t *m = NULL;
|
||||
efi_status_t status;
|
||||
@@ -96,19 +97,19 @@ efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg,
|
||||
*map->map_size = *map->desc_size * 32;
|
||||
*map->buff_size = *map->map_size;
|
||||
again:
|
||||
status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
|
||||
*map->map_size, (void **)&m);
|
||||
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA,
|
||||
*map->map_size, (void **)&m);
|
||||
if (status != EFI_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
*map->desc_size = 0;
|
||||
key = 0;
|
||||
status = efi_call_early(get_memory_map, map->map_size, m,
|
||||
&key, map->desc_size, &desc_version);
|
||||
status = efi_bs_call(get_memory_map, map->map_size, m,
|
||||
&key, map->desc_size, &desc_version);
|
||||
if (status == EFI_BUFFER_TOO_SMALL ||
|
||||
!mmap_has_headroom(*map->buff_size, *map->map_size,
|
||||
*map->desc_size)) {
|
||||
efi_call_early(free_pool, m);
|
||||
efi_bs_call(free_pool, m);
|
||||
/*
|
||||
* Make sure there is some entries of headroom so that the
|
||||
* buffer can be reused for a new map after allocations are
|
||||
@@ -122,7 +123,7 @@ again:
|
||||
}
|
||||
|
||||
if (status != EFI_SUCCESS)
|
||||
efi_call_early(free_pool, m);
|
||||
efi_bs_call(free_pool, m);
|
||||
|
||||
if (map->key_ptr && status == EFI_SUCCESS)
|
||||
*map->key_ptr = key;
|
||||
@@ -135,7 +136,7 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
unsigned long get_dram_base(efi_system_table_t *sys_table_arg)
|
||||
unsigned long get_dram_base(void)
|
||||
{
|
||||
efi_status_t status;
|
||||
unsigned long map_size, buff_size;
|
||||
@@ -151,7 +152,7 @@ unsigned long get_dram_base(efi_system_table_t *sys_table_arg)
|
||||
boot_map.key_ptr = NULL;
|
||||
boot_map.buff_size = &buff_size;
|
||||
|
||||
status = efi_get_memory_map(sys_table_arg, &boot_map);
|
||||
status = efi_get_memory_map(&boot_map);
|
||||
if (status != EFI_SUCCESS)
|
||||
return membase;
|
||||
|
||||
@@ -164,7 +165,7 @@ unsigned long get_dram_base(efi_system_table_t *sys_table_arg)
|
||||
}
|
||||
}
|
||||
|
||||
efi_call_early(free_pool, map.map);
|
||||
efi_bs_call(free_pool, map.map);
|
||||
|
||||
return membase;
|
||||
}
|
||||
@@ -172,8 +173,7 @@ unsigned long get_dram_base(efi_system_table_t *sys_table_arg)
|
||||
/*
|
||||
* Allocate at the highest possible address that is not above 'max'.
|
||||
*/
|
||||
efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg,
|
||||
unsigned long size, unsigned long align,
|
||||
efi_status_t efi_high_alloc(unsigned long size, unsigned long align,
|
||||
unsigned long *addr, unsigned long max)
|
||||
{
|
||||
unsigned long map_size, desc_size, buff_size;
|
||||
@@ -191,7 +191,7 @@ efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg,
|
||||
boot_map.key_ptr = NULL;
|
||||
boot_map.buff_size = &buff_size;
|
||||
|
||||
status = efi_get_memory_map(sys_table_arg, &boot_map);
|
||||
status = efi_get_memory_map(&boot_map);
|
||||
if (status != EFI_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
@@ -251,9 +251,8 @@ again:
|
||||
if (!max_addr)
|
||||
status = EFI_NOT_FOUND;
|
||||
else {
|
||||
status = efi_call_early(allocate_pages,
|
||||
EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
|
||||
nr_pages, &max_addr);
|
||||
status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS,
|
||||
EFI_LOADER_DATA, nr_pages, &max_addr);
|
||||
if (status != EFI_SUCCESS) {
|
||||
max = max_addr;
|
||||
max_addr = 0;
|
||||
@@ -263,7 +262,7 @@ again:
|
||||
*addr = max_addr;
|
||||
}
|
||||
|
||||
efi_call_early(free_pool, map);
|
||||
efi_bs_call(free_pool, map);
|
||||
fail:
|
||||
return status;
|
||||
}
|
||||
@@ -271,8 +270,7 @@ fail:
|
||||
/*
|
||||
* Allocate at the lowest possible address that is not below 'min'.
|
||||
*/
|
||||
efi_status_t efi_low_alloc_above(efi_system_table_t *sys_table_arg,
|
||||
unsigned long size, unsigned long align,
|
||||
efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align,
|
||||
unsigned long *addr, unsigned long min)
|
||||
{
|
||||
unsigned long map_size, desc_size, buff_size;
|
||||
@@ -289,7 +287,7 @@ efi_status_t efi_low_alloc_above(efi_system_table_t *sys_table_arg,
|
||||
boot_map.key_ptr = NULL;
|
||||
boot_map.buff_size = &buff_size;
|
||||
|
||||
status = efi_get_memory_map(sys_table_arg, &boot_map);
|
||||
status = efi_get_memory_map(&boot_map);
|
||||
if (status != EFI_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
@@ -331,9 +329,8 @@ efi_status_t efi_low_alloc_above(efi_system_table_t *sys_table_arg,
|
||||
if ((start + size) > end)
|
||||
continue;
|
||||
|
||||
status = efi_call_early(allocate_pages,
|
||||
EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
|
||||
nr_pages, &start);
|
||||
status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS,
|
||||
EFI_LOADER_DATA, nr_pages, &start);
|
||||
if (status == EFI_SUCCESS) {
|
||||
*addr = start;
|
||||
break;
|
||||
@@ -343,13 +340,12 @@ efi_status_t efi_low_alloc_above(efi_system_table_t *sys_table_arg,
|
||||
if (i == map_size / desc_size)
|
||||
status = EFI_NOT_FOUND;
|
||||
|
||||
efi_call_early(free_pool, map);
|
||||
efi_bs_call(free_pool, map);
|
||||
fail:
|
||||
return status;
|
||||
}
|
||||
|
||||
void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
|
||||
unsigned long addr)
|
||||
void efi_free(unsigned long size, unsigned long addr)
|
||||
{
|
||||
unsigned long nr_pages;
|
||||
|
||||
@@ -357,12 +353,11 @@ void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
|
||||
return;
|
||||
|
||||
nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
|
||||
efi_call_early(free_pages, addr, nr_pages);
|
||||
efi_bs_call(free_pages, addr, nr_pages);
|
||||
}
|
||||
|
||||
static efi_status_t efi_file_size(efi_system_table_t *sys_table_arg, void *__fh,
|
||||
efi_char16_t *filename_16, void **handle,
|
||||
u64 *file_sz)
|
||||
static efi_status_t efi_file_size(void *__fh, efi_char16_t *filename_16,
|
||||
void **handle, u64 *file_sz)
|
||||
{
|
||||
efi_file_handle_t *h, *fh = __fh;
|
||||
efi_file_info_t *info;
|
||||
@@ -370,81 +365,75 @@ static efi_status_t efi_file_size(efi_system_table_t *sys_table_arg, void *__fh,
|
||||
efi_guid_t info_guid = EFI_FILE_INFO_ID;
|
||||
unsigned long info_sz;
|
||||
|
||||
status = efi_call_proto(efi_file_handle, open, fh, &h, filename_16,
|
||||
EFI_FILE_MODE_READ, (u64)0);
|
||||
status = fh->open(fh, &h, filename_16, EFI_FILE_MODE_READ, 0);
|
||||
if (status != EFI_SUCCESS) {
|
||||
efi_printk(sys_table_arg, "Failed to open file: ");
|
||||
efi_char16_printk(sys_table_arg, filename_16);
|
||||
efi_printk(sys_table_arg, "\n");
|
||||
efi_printk("Failed to open file: ");
|
||||
efi_char16_printk(filename_16);
|
||||
efi_printk("\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
*handle = h;
|
||||
|
||||
info_sz = 0;
|
||||
status = efi_call_proto(efi_file_handle, get_info, h, &info_guid,
|
||||
&info_sz, NULL);
|
||||
status = h->get_info(h, &info_guid, &info_sz, NULL);
|
||||
if (status != EFI_BUFFER_TOO_SMALL) {
|
||||
efi_printk(sys_table_arg, "Failed to get file info size\n");
|
||||
efi_printk("Failed to get file info size\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
grow:
|
||||
status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
|
||||
info_sz, (void **)&info);
|
||||
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, info_sz,
|
||||
(void **)&info);
|
||||
if (status != EFI_SUCCESS) {
|
||||
efi_printk(sys_table_arg, "Failed to alloc mem for file info\n");
|
||||
efi_printk("Failed to alloc mem for file info\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
status = efi_call_proto(efi_file_handle, get_info, h, &info_guid,
|
||||
&info_sz, info);
|
||||
status = h->get_info(h, &info_guid, &info_sz, info);
|
||||
if (status == EFI_BUFFER_TOO_SMALL) {
|
||||
efi_call_early(free_pool, info);
|
||||
efi_bs_call(free_pool, info);
|
||||
goto grow;
|
||||
}
|
||||
|
||||
*file_sz = info->file_size;
|
||||
efi_call_early(free_pool, info);
|
||||
efi_bs_call(free_pool, info);
|
||||
|
||||
if (status != EFI_SUCCESS)
|
||||
efi_printk(sys_table_arg, "Failed to get initrd info\n");
|
||||
efi_printk("Failed to get initrd info\n");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static efi_status_t efi_file_read(void *handle, unsigned long *size, void *addr)
|
||||
static efi_status_t efi_file_read(efi_file_handle_t *handle,
|
||||
unsigned long *size, void *addr)
|
||||
{
|
||||
return efi_call_proto(efi_file_handle, read, handle, size, addr);
|
||||
return handle->read(handle, size, addr);
|
||||
}
|
||||
|
||||
static efi_status_t efi_file_close(void *handle)
|
||||
static efi_status_t efi_file_close(efi_file_handle_t *handle)
|
||||
{
|
||||
return efi_call_proto(efi_file_handle, close, handle);
|
||||
return handle->close(handle);
|
||||
}
|
||||
|
||||
static efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
|
||||
efi_loaded_image_t *image,
|
||||
static efi_status_t efi_open_volume(efi_loaded_image_t *image,
|
||||
efi_file_handle_t **__fh)
|
||||
{
|
||||
efi_file_io_interface_t *io;
|
||||
efi_file_handle_t *fh;
|
||||
efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
|
||||
efi_status_t status;
|
||||
void *handle = (void *)(unsigned long)efi_table_attr(efi_loaded_image,
|
||||
device_handle,
|
||||
image);
|
||||
efi_handle_t handle = image->device_handle;
|
||||
|
||||
status = efi_call_early(handle_protocol, handle,
|
||||
&fs_proto, (void **)&io);
|
||||
status = efi_bs_call(handle_protocol, handle, &fs_proto, (void **)&io);
|
||||
if (status != EFI_SUCCESS) {
|
||||
efi_printk(sys_table_arg, "Failed to handle fs_proto\n");
|
||||
efi_printk("Failed to handle fs_proto\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
status = efi_call_proto(efi_file_io_interface, open_volume, io, &fh);
|
||||
status = io->open_volume(io, &fh);
|
||||
if (status != EFI_SUCCESS)
|
||||
efi_printk(sys_table_arg, "Failed to open volume\n");
|
||||
efi_printk("Failed to open volume\n");
|
||||
else
|
||||
*__fh = fh;
|
||||
|
||||
@@ -465,11 +454,11 @@ efi_status_t efi_parse_options(char const *cmdline)
|
||||
|
||||
str = strstr(cmdline, "nokaslr");
|
||||
if (str == cmdline || (str && str > cmdline && *(str - 1) == ' '))
|
||||
__nokaslr = 1;
|
||||
efi_nokaslr = true;
|
||||
|
||||
str = strstr(cmdline, "quiet");
|
||||
if (str == cmdline || (str && str > cmdline && *(str - 1) == ' '))
|
||||
__quiet = 1;
|
||||
efi_quiet = true;
|
||||
|
||||
/*
|
||||
* If no EFI parameters were specified on the cmdline we've got
|
||||
@@ -489,18 +478,28 @@ efi_status_t efi_parse_options(char const *cmdline)
|
||||
while (*str && *str != ' ') {
|
||||
if (!strncmp(str, "nochunk", 7)) {
|
||||
str += strlen("nochunk");
|
||||
__chunk_size = -1UL;
|
||||
efi_chunk_size = -1UL;
|
||||
}
|
||||
|
||||
if (!strncmp(str, "novamap", 7)) {
|
||||
str += strlen("novamap");
|
||||
__novamap = 1;
|
||||
efi_novamap = true;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_EFI_SOFT_RESERVE) &&
|
||||
!strncmp(str, "nosoftreserve", 7)) {
|
||||
str += strlen("nosoftreserve");
|
||||
efi_nosoftreserve = 1;
|
||||
efi_nosoftreserve = true;
|
||||
}
|
||||
|
||||
if (!strncmp(str, "disable_early_pci_dma", 21)) {
|
||||
str += strlen("disable_early_pci_dma");
|
||||
efi_disable_pci_dma = true;
|
||||
}
|
||||
|
||||
if (!strncmp(str, "no_disable_early_pci_dma", 24)) {
|
||||
str += strlen("no_disable_early_pci_dma");
|
||||
efi_disable_pci_dma = false;
|
||||
}
|
||||
|
||||
/* Group words together, delimited by "," */
|
||||
@@ -520,8 +519,7 @@ efi_status_t efi_parse_options(char const *cmdline)
|
||||
* We only support loading a file from the same filesystem as
|
||||
* the kernel image.
|
||||
*/
|
||||
efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
|
||||
efi_loaded_image_t *image,
|
||||
efi_status_t handle_cmdline_files(efi_loaded_image_t *image,
|
||||
char *cmd_line, char *option_string,
|
||||
unsigned long max_addr,
|
||||
unsigned long *load_addr,
|
||||
@@ -570,10 +568,10 @@ efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
|
||||
if (!nr_files)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
|
||||
nr_files * sizeof(*files), (void **)&files);
|
||||
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA,
|
||||
nr_files * sizeof(*files), (void **)&files);
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table_arg, "Failed to alloc mem for file handle list\n");
|
||||
pr_efi_err("Failed to alloc mem for file handle list\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -612,13 +610,13 @@ efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
|
||||
|
||||
/* Only open the volume once. */
|
||||
if (!i) {
|
||||
status = efi_open_volume(sys_table_arg, image, &fh);
|
||||
status = efi_open_volume(image, &fh);
|
||||
if (status != EFI_SUCCESS)
|
||||
goto free_files;
|
||||
}
|
||||
|
||||
status = efi_file_size(sys_table_arg, fh, filename_16,
|
||||
(void **)&file->handle, &file->size);
|
||||
status = efi_file_size(fh, filename_16, (void **)&file->handle,
|
||||
&file->size);
|
||||
if (status != EFI_SUCCESS)
|
||||
goto close_handles;
|
||||
|
||||
@@ -633,16 +631,16 @@ efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
|
||||
* so allocate enough memory for all the files. This is used
|
||||
* for loading multiple files.
|
||||
*/
|
||||
status = efi_high_alloc(sys_table_arg, file_size_total, 0x1000,
|
||||
&file_addr, max_addr);
|
||||
status = efi_high_alloc(file_size_total, 0x1000, &file_addr,
|
||||
max_addr);
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table_arg, "Failed to alloc highmem for files\n");
|
||||
pr_efi_err("Failed to alloc highmem for files\n");
|
||||
goto close_handles;
|
||||
}
|
||||
|
||||
/* We've run out of free low memory. */
|
||||
if (file_addr > max_addr) {
|
||||
pr_efi_err(sys_table_arg, "We've run out of free low memory\n");
|
||||
pr_efi_err("We've run out of free low memory\n");
|
||||
status = EFI_INVALID_PARAMETER;
|
||||
goto free_file_total;
|
||||
}
|
||||
@@ -655,8 +653,8 @@ efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
|
||||
while (size) {
|
||||
unsigned long chunksize;
|
||||
|
||||
if (IS_ENABLED(CONFIG_X86) && size > __chunk_size)
|
||||
chunksize = __chunk_size;
|
||||
if (IS_ENABLED(CONFIG_X86) && size > efi_chunk_size)
|
||||
chunksize = efi_chunk_size;
|
||||
else
|
||||
chunksize = size;
|
||||
|
||||
@@ -664,7 +662,7 @@ efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
|
||||
&chunksize,
|
||||
(void *)addr);
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table_arg, "Failed to read file\n");
|
||||
pr_efi_err("Failed to read file\n");
|
||||
goto free_file_total;
|
||||
}
|
||||
addr += chunksize;
|
||||
@@ -676,7 +674,7 @@ efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
|
||||
|
||||
}
|
||||
|
||||
efi_call_early(free_pool, files);
|
||||
efi_bs_call(free_pool, files);
|
||||
|
||||
*load_addr = file_addr;
|
||||
*load_size = file_size_total;
|
||||
@@ -684,13 +682,13 @@ efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
|
||||
return status;
|
||||
|
||||
free_file_total:
|
||||
efi_free(sys_table_arg, file_size_total, file_addr);
|
||||
efi_free(file_size_total, file_addr);
|
||||
|
||||
close_handles:
|
||||
for (k = j; k < i; k++)
|
||||
efi_file_close(files[k].handle);
|
||||
free_files:
|
||||
efi_call_early(free_pool, files);
|
||||
efi_bs_call(free_pool, files);
|
||||
fail:
|
||||
*load_addr = 0;
|
||||
*load_size = 0;
|
||||
@@ -707,8 +705,7 @@ fail:
|
||||
* address is not available the lowest available address will
|
||||
* be used.
|
||||
*/
|
||||
efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
|
||||
unsigned long *image_addr,
|
||||
efi_status_t efi_relocate_kernel(unsigned long *image_addr,
|
||||
unsigned long image_size,
|
||||
unsigned long alloc_size,
|
||||
unsigned long preferred_addr,
|
||||
@@ -737,20 +734,19 @@ efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
|
||||
* as possible while respecting the required alignment.
|
||||
*/
|
||||
nr_pages = round_up(alloc_size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
|
||||
status = efi_call_early(allocate_pages,
|
||||
EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
|
||||
nr_pages, &efi_addr);
|
||||
status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS,
|
||||
EFI_LOADER_DATA, nr_pages, &efi_addr);
|
||||
new_addr = efi_addr;
|
||||
/*
|
||||
* If preferred address allocation failed allocate as low as
|
||||
* possible.
|
||||
*/
|
||||
if (status != EFI_SUCCESS) {
|
||||
status = efi_low_alloc_above(sys_table_arg, alloc_size,
|
||||
alignment, &new_addr, min_addr);
|
||||
status = efi_low_alloc_above(alloc_size, alignment, &new_addr,
|
||||
min_addr);
|
||||
}
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table_arg, "Failed to allocate usable memory for kernel.\n");
|
||||
pr_efi_err("Failed to allocate usable memory for kernel.\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -824,8 +820,7 @@ static u8 *efi_utf16_to_utf8(u8 *dst, const u16 *src, int n)
|
||||
* Size of memory allocated return in *cmd_line_len.
|
||||
* Returns NULL on error.
|
||||
*/
|
||||
char *efi_convert_cmdline(efi_system_table_t *sys_table_arg,
|
||||
efi_loaded_image_t *image,
|
||||
char *efi_convert_cmdline(efi_loaded_image_t *image,
|
||||
int *cmd_line_len)
|
||||
{
|
||||
const u16 *s2;
|
||||
@@ -854,8 +849,8 @@ char *efi_convert_cmdline(efi_system_table_t *sys_table_arg,
|
||||
|
||||
options_bytes++; /* NUL termination */
|
||||
|
||||
status = efi_high_alloc(sys_table_arg, options_bytes, 0,
|
||||
&cmdline_addr, MAX_CMDLINE_ADDRESS);
|
||||
status = efi_high_alloc(options_bytes, 0, &cmdline_addr,
|
||||
MAX_CMDLINE_ADDRESS);
|
||||
if (status != EFI_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
@@ -877,24 +872,26 @@ char *efi_convert_cmdline(efi_system_table_t *sys_table_arg,
|
||||
* specific structure may be passed to the function via priv. The client
|
||||
* function may be called multiple times.
|
||||
*/
|
||||
efi_status_t efi_exit_boot_services(efi_system_table_t *sys_table_arg,
|
||||
void *handle,
|
||||
efi_status_t efi_exit_boot_services(void *handle,
|
||||
struct efi_boot_memmap *map,
|
||||
void *priv,
|
||||
efi_exit_boot_map_processing priv_func)
|
||||
{
|
||||
efi_status_t status;
|
||||
|
||||
status = efi_get_memory_map(sys_table_arg, map);
|
||||
status = efi_get_memory_map(map);
|
||||
|
||||
if (status != EFI_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
status = priv_func(sys_table_arg, map, priv);
|
||||
status = priv_func(map, priv);
|
||||
if (status != EFI_SUCCESS)
|
||||
goto free_map;
|
||||
|
||||
status = efi_call_early(exit_boot_services, handle, *map->key_ptr);
|
||||
if (efi_disable_pci_dma)
|
||||
efi_pci_disable_bridge_busmaster();
|
||||
|
||||
status = efi_bs_call(exit_boot_services, handle, *map->key_ptr);
|
||||
|
||||
if (status == EFI_INVALID_PARAMETER) {
|
||||
/*
|
||||
@@ -911,23 +908,23 @@ efi_status_t efi_exit_boot_services(efi_system_table_t *sys_table_arg,
|
||||
* to get_memory_map() is expected to succeed here.
|
||||
*/
|
||||
*map->map_size = *map->buff_size;
|
||||
status = efi_call_early(get_memory_map,
|
||||
map->map_size,
|
||||
*map->map,
|
||||
map->key_ptr,
|
||||
map->desc_size,
|
||||
map->desc_ver);
|
||||
status = efi_bs_call(get_memory_map,
|
||||
map->map_size,
|
||||
*map->map,
|
||||
map->key_ptr,
|
||||
map->desc_size,
|
||||
map->desc_ver);
|
||||
|
||||
/* exit_boot_services() was called, thus cannot free */
|
||||
if (status != EFI_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
status = priv_func(sys_table_arg, map, priv);
|
||||
status = priv_func(map, priv);
|
||||
/* exit_boot_services() was called, thus cannot free */
|
||||
if (status != EFI_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
status = efi_call_early(exit_boot_services, handle, *map->key_ptr);
|
||||
status = efi_bs_call(exit_boot_services, handle, *map->key_ptr);
|
||||
}
|
||||
|
||||
/* exit_boot_services() was called, thus cannot free */
|
||||
@@ -937,38 +934,31 @@ efi_status_t efi_exit_boot_services(efi_system_table_t *sys_table_arg,
|
||||
return EFI_SUCCESS;
|
||||
|
||||
free_map:
|
||||
efi_call_early(free_pool, *map->map);
|
||||
efi_bs_call(free_pool, *map->map);
|
||||
fail:
|
||||
return status;
|
||||
}
|
||||
|
||||
#define GET_EFI_CONFIG_TABLE(bits) \
|
||||
static void *get_efi_config_table##bits(efi_system_table_t *_sys_table, \
|
||||
efi_guid_t guid) \
|
||||
{ \
|
||||
efi_system_table_##bits##_t *sys_table; \
|
||||
efi_config_table_##bits##_t *tables; \
|
||||
int i; \
|
||||
\
|
||||
sys_table = (typeof(sys_table))_sys_table; \
|
||||
tables = (typeof(tables))(unsigned long)sys_table->tables; \
|
||||
\
|
||||
for (i = 0; i < sys_table->nr_tables; i++) { \
|
||||
if (efi_guidcmp(tables[i].guid, guid) != 0) \
|
||||
continue; \
|
||||
\
|
||||
return (void *)(unsigned long)tables[i].table; \
|
||||
} \
|
||||
\
|
||||
return NULL; \
|
||||
}
|
||||
GET_EFI_CONFIG_TABLE(32)
|
||||
GET_EFI_CONFIG_TABLE(64)
|
||||
|
||||
void *get_efi_config_table(efi_system_table_t *sys_table, efi_guid_t guid)
|
||||
void *get_efi_config_table(efi_guid_t guid)
|
||||
{
|
||||
if (efi_is_64bit())
|
||||
return get_efi_config_table64(sys_table, guid);
|
||||
else
|
||||
return get_efi_config_table32(sys_table, guid);
|
||||
unsigned long tables = efi_table_attr(efi_system_table(), tables);
|
||||
int nr_tables = efi_table_attr(efi_system_table(), nr_tables);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_tables; i++) {
|
||||
efi_config_table_t *t = (void *)tables;
|
||||
|
||||
if (efi_guidcmp(t->guid, guid) == 0)
|
||||
return efi_table_attr(t, table);
|
||||
|
||||
tables += efi_is_native() ? sizeof(efi_config_table_t)
|
||||
: sizeof(efi_config_table_32_t);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void efi_char16_printk(efi_char16_t *str)
|
||||
{
|
||||
efi_call_proto(efi_table_attr(efi_system_table(), con_out),
|
||||
output_string, str);
|
||||
}
|
||||
|
@@ -25,22 +25,30 @@
|
||||
#define EFI_ALLOC_ALIGN EFI_PAGE_SIZE
|
||||
#endif
|
||||
|
||||
extern int __pure nokaslr(void);
|
||||
extern int __pure is_quiet(void);
|
||||
extern int __pure novamap(void);
|
||||
#ifdef CONFIG_ARM
|
||||
#define __efistub_global __section(.data)
|
||||
#else
|
||||
#define __efistub_global
|
||||
#endif
|
||||
|
||||
#define pr_efi(sys_table, msg) do { \
|
||||
if (!is_quiet()) efi_printk(sys_table, "EFI stub: "msg); \
|
||||
extern bool __pure nokaslr(void);
|
||||
extern bool __pure is_quiet(void);
|
||||
extern bool __pure novamap(void);
|
||||
|
||||
extern __pure efi_system_table_t *efi_system_table(void);
|
||||
|
||||
#define pr_efi(msg) do { \
|
||||
if (!is_quiet()) efi_printk("EFI stub: "msg); \
|
||||
} while (0)
|
||||
|
||||
#define pr_efi_err(sys_table, msg) efi_printk(sys_table, "EFI stub: ERROR: "msg)
|
||||
#define pr_efi_err(msg) efi_printk("EFI stub: ERROR: "msg)
|
||||
|
||||
void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
|
||||
void efi_char16_printk(efi_char16_t *);
|
||||
void efi_char16_printk(efi_char16_t *);
|
||||
|
||||
unsigned long get_dram_base(efi_system_table_t *sys_table_arg);
|
||||
unsigned long get_dram_base(void);
|
||||
|
||||
efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
|
||||
void *handle,
|
||||
efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
|
||||
unsigned long *new_fdt_addr,
|
||||
unsigned long max_addr,
|
||||
u64 initrd_addr, u64 initrd_size,
|
||||
@@ -48,22 +56,20 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
|
||||
unsigned long fdt_addr,
|
||||
unsigned long fdt_size);
|
||||
|
||||
void *get_fdt(efi_system_table_t *sys_table, unsigned long *fdt_size);
|
||||
void *get_fdt(unsigned long *fdt_size);
|
||||
|
||||
void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size,
|
||||
unsigned long desc_size, efi_memory_desc_t *runtime_map,
|
||||
int *count);
|
||||
|
||||
efi_status_t efi_get_random_bytes(efi_system_table_t *sys_table,
|
||||
unsigned long size, u8 *out);
|
||||
efi_status_t efi_get_random_bytes(unsigned long size, u8 *out);
|
||||
|
||||
efi_status_t efi_random_alloc(efi_system_table_t *sys_table_arg,
|
||||
unsigned long size, unsigned long align,
|
||||
efi_status_t efi_random_alloc(unsigned long size, unsigned long align,
|
||||
unsigned long *addr, unsigned long random_seed);
|
||||
|
||||
efi_status_t check_platform_features(efi_system_table_t *sys_table_arg);
|
||||
efi_status_t check_platform_features(void);
|
||||
|
||||
void *get_efi_config_table(efi_system_table_t *sys_table, efi_guid_t guid);
|
||||
void *get_efi_config_table(efi_guid_t guid);
|
||||
|
||||
/* Helper macros for the usual case of using simple C variables: */
|
||||
#ifndef fdt_setprop_inplace_var
|
||||
@@ -76,4 +82,12 @@ void *get_efi_config_table(efi_system_table_t *sys_table, efi_guid_t guid);
|
||||
fdt_setprop((fdt), (node_offset), (name), &(var), sizeof(var))
|
||||
#endif
|
||||
|
||||
#define get_efi_var(name, vendor, ...) \
|
||||
efi_rt_call(get_variable, (efi_char16_t *)(name), \
|
||||
(efi_guid_t *)(vendor), __VA_ARGS__)
|
||||
|
||||
#define set_efi_var(name, vendor, ...) \
|
||||
efi_rt_call(set_variable, (efi_char16_t *)(name), \
|
||||
(efi_guid_t *)(vendor), __VA_ARGS__)
|
||||
|
||||
#endif
|
||||
|
@@ -16,7 +16,7 @@
|
||||
#define EFI_DT_ADDR_CELLS_DEFAULT 2
|
||||
#define EFI_DT_SIZE_CELLS_DEFAULT 2
|
||||
|
||||
static void fdt_update_cell_size(efi_system_table_t *sys_table, void *fdt)
|
||||
static void fdt_update_cell_size(void *fdt)
|
||||
{
|
||||
int offset;
|
||||
|
||||
@@ -27,8 +27,7 @@ static void fdt_update_cell_size(efi_system_table_t *sys_table, void *fdt)
|
||||
fdt_setprop_u32(fdt, offset, "#size-cells", EFI_DT_SIZE_CELLS_DEFAULT);
|
||||
}
|
||||
|
||||
static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
|
||||
unsigned long orig_fdt_size,
|
||||
static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
|
||||
void *fdt, int new_fdt_size, char *cmdline_ptr,
|
||||
u64 initrd_addr, u64 initrd_size)
|
||||
{
|
||||
@@ -40,7 +39,7 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
|
||||
/* Do some checks on provided FDT, if it exists: */
|
||||
if (orig_fdt) {
|
||||
if (fdt_check_header(orig_fdt)) {
|
||||
pr_efi_err(sys_table, "Device Tree header not valid!\n");
|
||||
pr_efi_err("Device Tree header not valid!\n");
|
||||
return EFI_LOAD_ERROR;
|
||||
}
|
||||
/*
|
||||
@@ -48,7 +47,7 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
|
||||
* configuration table:
|
||||
*/
|
||||
if (orig_fdt_size && fdt_totalsize(orig_fdt) > orig_fdt_size) {
|
||||
pr_efi_err(sys_table, "Truncated device tree! foo!\n");
|
||||
pr_efi_err("Truncated device tree! foo!\n");
|
||||
return EFI_LOAD_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -62,7 +61,7 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
|
||||
* Any failure from the following function is
|
||||
* non-critical:
|
||||
*/
|
||||
fdt_update_cell_size(sys_table, fdt);
|
||||
fdt_update_cell_size(fdt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +110,7 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
|
||||
|
||||
/* Add FDT entries for EFI runtime services in chosen node. */
|
||||
node = fdt_subnode_offset(fdt, 0, "chosen");
|
||||
fdt_val64 = cpu_to_fdt64((u64)(unsigned long)sys_table);
|
||||
fdt_val64 = cpu_to_fdt64((u64)(unsigned long)efi_system_table());
|
||||
|
||||
status = fdt_setprop_var(fdt, node, "linux,uefi-system-table", fdt_val64);
|
||||
if (status)
|
||||
@@ -140,7 +139,7 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
|
||||
if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
|
||||
efi_status_t efi_status;
|
||||
|
||||
efi_status = efi_get_random_bytes(sys_table, sizeof(fdt_val64),
|
||||
efi_status = efi_get_random_bytes(sizeof(fdt_val64),
|
||||
(u8 *)&fdt_val64);
|
||||
if (efi_status == EFI_SUCCESS) {
|
||||
status = fdt_setprop_var(fdt, node, "kaslr-seed", fdt_val64);
|
||||
@@ -210,8 +209,7 @@ struct exit_boot_struct {
|
||||
void *new_fdt_addr;
|
||||
};
|
||||
|
||||
static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg,
|
||||
struct efi_boot_memmap *map,
|
||||
static efi_status_t exit_boot_func(struct efi_boot_memmap *map,
|
||||
void *priv)
|
||||
{
|
||||
struct exit_boot_struct *p = priv;
|
||||
@@ -244,8 +242,7 @@ static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg,
|
||||
* with the final memory map in it.
|
||||
*/
|
||||
|
||||
efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
|
||||
void *handle,
|
||||
efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
|
||||
unsigned long *new_fdt_addr,
|
||||
unsigned long max_addr,
|
||||
u64 initrd_addr, u64 initrd_size,
|
||||
@@ -275,19 +272,19 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
|
||||
* subsequent allocations adding entries, since they could not affect
|
||||
* the number of EFI_MEMORY_RUNTIME regions.
|
||||
*/
|
||||
status = efi_get_memory_map(sys_table, &map);
|
||||
status = efi_get_memory_map(&map);
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table, "Unable to retrieve UEFI memory map.\n");
|
||||
pr_efi_err("Unable to retrieve UEFI memory map.\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
pr_efi(sys_table, "Exiting boot services and installing virtual address map...\n");
|
||||
pr_efi("Exiting boot services and installing virtual address map...\n");
|
||||
|
||||
map.map = &memory_map;
|
||||
status = efi_high_alloc(sys_table, MAX_FDT_SIZE, EFI_FDT_ALIGN,
|
||||
status = efi_high_alloc(MAX_FDT_SIZE, EFI_FDT_ALIGN,
|
||||
new_fdt_addr, max_addr);
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table, "Unable to allocate memory for new device tree.\n");
|
||||
pr_efi_err("Unable to allocate memory for new device tree.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -295,16 +292,16 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
|
||||
* Now that we have done our final memory allocation (and free)
|
||||
* we can get the memory map key needed for exit_boot_services().
|
||||
*/
|
||||
status = efi_get_memory_map(sys_table, &map);
|
||||
status = efi_get_memory_map(&map);
|
||||
if (status != EFI_SUCCESS)
|
||||
goto fail_free_new_fdt;
|
||||
|
||||
status = update_fdt(sys_table, (void *)fdt_addr, fdt_size,
|
||||
status = update_fdt((void *)fdt_addr, fdt_size,
|
||||
(void *)*new_fdt_addr, MAX_FDT_SIZE, cmdline_ptr,
|
||||
initrd_addr, initrd_size);
|
||||
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err(sys_table, "Unable to construct new device tree.\n");
|
||||
pr_efi_err("Unable to construct new device tree.\n");
|
||||
goto fail_free_new_fdt;
|
||||
}
|
||||
|
||||
@@ -313,7 +310,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
|
||||
priv.runtime_entry_count = &runtime_entry_count;
|
||||
priv.new_fdt_addr = (void *)*new_fdt_addr;
|
||||
|
||||
status = efi_exit_boot_services(sys_table, handle, &map, &priv, exit_boot_func);
|
||||
status = efi_exit_boot_services(handle, &map, &priv, exit_boot_func);
|
||||
|
||||
if (status == EFI_SUCCESS) {
|
||||
efi_set_virtual_address_map_t *svam;
|
||||
@@ -322,7 +319,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
|
||||
return EFI_SUCCESS;
|
||||
|
||||
/* Install the new virtual address map */
|
||||
svam = sys_table->runtime->set_virtual_address_map;
|
||||
svam = efi_system_table()->runtime->set_virtual_address_map;
|
||||
status = svam(runtime_entry_count * desc_size, desc_size,
|
||||
desc_ver, runtime_map);
|
||||
|
||||
@@ -350,28 +347,28 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
pr_efi_err(sys_table, "Exit boot services failed.\n");
|
||||
pr_efi_err("Exit boot services failed.\n");
|
||||
|
||||
fail_free_new_fdt:
|
||||
efi_free(sys_table, MAX_FDT_SIZE, *new_fdt_addr);
|
||||
efi_free(MAX_FDT_SIZE, *new_fdt_addr);
|
||||
|
||||
fail:
|
||||
sys_table->boottime->free_pool(runtime_map);
|
||||
efi_system_table()->boottime->free_pool(runtime_map);
|
||||
|
||||
return EFI_LOAD_ERROR;
|
||||
}
|
||||
|
||||
void *get_fdt(efi_system_table_t *sys_table, unsigned long *fdt_size)
|
||||
void *get_fdt(unsigned long *fdt_size)
|
||||
{
|
||||
void *fdt;
|
||||
|
||||
fdt = get_efi_config_table(sys_table, DEVICE_TREE_GUID);
|
||||
fdt = get_efi_config_table(DEVICE_TREE_GUID);
|
||||
|
||||
if (!fdt)
|
||||
return NULL;
|
||||
|
||||
if (fdt_check_header(fdt) != 0) {
|
||||
pr_efi_err(sys_table, "Invalid header detected on UEFI supplied FDT, ignoring ...\n");
|
||||
pr_efi_err("Invalid header detected on UEFI supplied FDT, ignoring ...\n");
|
||||
return NULL;
|
||||
}
|
||||
*fdt_size = fdt_totalsize(fdt);
|
||||
|
@@ -10,6 +10,8 @@
|
||||
#include <asm/efi.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#include "efistub.h"
|
||||
|
||||
static void find_bits(unsigned long mask, u8 *pos, u8 *size)
|
||||
{
|
||||
u8 first, len;
|
||||
@@ -35,7 +37,7 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size)
|
||||
|
||||
static void
|
||||
setup_pixel_info(struct screen_info *si, u32 pixels_per_scan_line,
|
||||
struct efi_pixel_bitmask pixel_info, int pixel_format)
|
||||
efi_pixel_bitmask_t pixel_info, int pixel_format)
|
||||
{
|
||||
if (pixel_format == PIXEL_RGB_RESERVED_8BIT_PER_COLOR) {
|
||||
si->lfb_depth = 32;
|
||||
@@ -83,48 +85,42 @@ setup_pixel_info(struct screen_info *si, u32 pixels_per_scan_line,
|
||||
}
|
||||
}
|
||||
|
||||
static efi_status_t
|
||||
setup_gop32(efi_system_table_t *sys_table_arg, struct screen_info *si,
|
||||
efi_guid_t *proto, unsigned long size, void **gop_handle)
|
||||
static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
|
||||
unsigned long size, void **handles)
|
||||
{
|
||||
struct efi_graphics_output_protocol_32 *gop32, *first_gop;
|
||||
unsigned long nr_gops;
|
||||
efi_graphics_output_protocol_t *gop, *first_gop;
|
||||
u16 width, height;
|
||||
u32 pixels_per_scan_line;
|
||||
u32 ext_lfb_base;
|
||||
u64 fb_base;
|
||||
struct efi_pixel_bitmask pixel_info;
|
||||
efi_physical_addr_t fb_base;
|
||||
efi_pixel_bitmask_t pixel_info;
|
||||
int pixel_format;
|
||||
efi_status_t status;
|
||||
u32 *handles = (u32 *)(unsigned long)gop_handle;
|
||||
efi_handle_t h;
|
||||
int i;
|
||||
|
||||
first_gop = NULL;
|
||||
gop32 = NULL;
|
||||
gop = NULL;
|
||||
|
||||
nr_gops = size / sizeof(u32);
|
||||
for (i = 0; i < nr_gops; i++) {
|
||||
struct efi_graphics_output_protocol_mode_32 *mode;
|
||||
struct efi_graphics_output_mode_info *info = NULL;
|
||||
for_each_efi_handle(h, handles, size, i) {
|
||||
efi_graphics_output_protocol_mode_t *mode;
|
||||
efi_graphics_output_mode_info_t *info = NULL;
|
||||
efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID;
|
||||
bool conout_found = false;
|
||||
void *dummy = NULL;
|
||||
efi_handle_t h = (efi_handle_t)(unsigned long)handles[i];
|
||||
u64 current_fb_base;
|
||||
efi_physical_addr_t current_fb_base;
|
||||
|
||||
status = efi_call_early(handle_protocol, h,
|
||||
proto, (void **)&gop32);
|
||||
status = efi_bs_call(handle_protocol, h, proto, (void **)&gop);
|
||||
if (status != EFI_SUCCESS)
|
||||
continue;
|
||||
|
||||
status = efi_call_early(handle_protocol, h,
|
||||
&conout_proto, &dummy);
|
||||
status = efi_bs_call(handle_protocol, h, &conout_proto, &dummy);
|
||||
if (status == EFI_SUCCESS)
|
||||
conout_found = true;
|
||||
|
||||
mode = (void *)(unsigned long)gop32->mode;
|
||||
info = (void *)(unsigned long)mode->info;
|
||||
current_fb_base = mode->frame_buffer_base;
|
||||
mode = efi_table_attr(gop, mode);
|
||||
info = efi_table_attr(mode, info);
|
||||
current_fb_base = efi_table_attr(mode, frame_buffer_base);
|
||||
|
||||
if ((!first_gop || conout_found) &&
|
||||
info->pixel_format != PIXEL_BLT_ONLY) {
|
||||
@@ -146,104 +142,7 @@ setup_gop32(efi_system_table_t *sys_table_arg, struct screen_info *si,
|
||||
* Once we've found a GOP supporting ConOut,
|
||||
* don't bother looking any further.
|
||||
*/
|
||||
first_gop = gop32;
|
||||
if (conout_found)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we find any GOPs? */
|
||||
if (!first_gop)
|
||||
return EFI_NOT_FOUND;
|
||||
|
||||
/* EFI framebuffer */
|
||||
si->orig_video_isVGA = VIDEO_TYPE_EFI;
|
||||
|
||||
si->lfb_width = width;
|
||||
si->lfb_height = height;
|
||||
si->lfb_base = fb_base;
|
||||
|
||||
ext_lfb_base = (u64)(unsigned long)fb_base >> 32;
|
||||
if (ext_lfb_base) {
|
||||
si->capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
|
||||
si->ext_lfb_base = ext_lfb_base;
|
||||
}
|
||||
|
||||
si->pages = 1;
|
||||
|
||||
setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format);
|
||||
|
||||
si->lfb_size = si->lfb_linelength * si->lfb_height;
|
||||
|
||||
si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static efi_status_t
|
||||
setup_gop64(efi_system_table_t *sys_table_arg, struct screen_info *si,
|
||||
efi_guid_t *proto, unsigned long size, void **gop_handle)
|
||||
{
|
||||
struct efi_graphics_output_protocol_64 *gop64, *first_gop;
|
||||
unsigned long nr_gops;
|
||||
u16 width, height;
|
||||
u32 pixels_per_scan_line;
|
||||
u32 ext_lfb_base;
|
||||
u64 fb_base;
|
||||
struct efi_pixel_bitmask pixel_info;
|
||||
int pixel_format;
|
||||
efi_status_t status;
|
||||
u64 *handles = (u64 *)(unsigned long)gop_handle;
|
||||
int i;
|
||||
|
||||
first_gop = NULL;
|
||||
gop64 = NULL;
|
||||
|
||||
nr_gops = size / sizeof(u64);
|
||||
for (i = 0; i < nr_gops; i++) {
|
||||
struct efi_graphics_output_protocol_mode_64 *mode;
|
||||
struct efi_graphics_output_mode_info *info = NULL;
|
||||
efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID;
|
||||
bool conout_found = false;
|
||||
void *dummy = NULL;
|
||||
efi_handle_t h = (efi_handle_t)(unsigned long)handles[i];
|
||||
u64 current_fb_base;
|
||||
|
||||
status = efi_call_early(handle_protocol, h,
|
||||
proto, (void **)&gop64);
|
||||
if (status != EFI_SUCCESS)
|
||||
continue;
|
||||
|
||||
status = efi_call_early(handle_protocol, h,
|
||||
&conout_proto, &dummy);
|
||||
if (status == EFI_SUCCESS)
|
||||
conout_found = true;
|
||||
|
||||
mode = (void *)(unsigned long)gop64->mode;
|
||||
info = (void *)(unsigned long)mode->info;
|
||||
current_fb_base = mode->frame_buffer_base;
|
||||
|
||||
if ((!first_gop || conout_found) &&
|
||||
info->pixel_format != PIXEL_BLT_ONLY) {
|
||||
/*
|
||||
* Systems that use the UEFI Console Splitter may
|
||||
* provide multiple GOP devices, not all of which are
|
||||
* backed by real hardware. The workaround is to search
|
||||
* for a GOP implementing the ConOut protocol, and if
|
||||
* one isn't found, to just fall back to the first GOP.
|
||||
*/
|
||||
width = info->horizontal_resolution;
|
||||
height = info->vertical_resolution;
|
||||
pixel_format = info->pixel_format;
|
||||
pixel_info = info->pixel_information;
|
||||
pixels_per_scan_line = info->pixels_per_scan_line;
|
||||
fb_base = current_fb_base;
|
||||
|
||||
/*
|
||||
* Once we've found a GOP supporting ConOut,
|
||||
* don't bother looking any further.
|
||||
*/
|
||||
first_gop = gop64;
|
||||
first_gop = gop;
|
||||
if (conout_found)
|
||||
break;
|
||||
}
|
||||
@@ -280,33 +179,25 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct screen_info *si,
|
||||
/*
|
||||
* See if we have Graphics Output Protocol
|
||||
*/
|
||||
efi_status_t efi_setup_gop(efi_system_table_t *sys_table_arg,
|
||||
struct screen_info *si, efi_guid_t *proto,
|
||||
efi_status_t efi_setup_gop(struct screen_info *si, efi_guid_t *proto,
|
||||
unsigned long size)
|
||||
{
|
||||
efi_status_t status;
|
||||
void **gop_handle = NULL;
|
||||
|
||||
status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
|
||||
size, (void **)&gop_handle);
|
||||
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size,
|
||||
(void **)&gop_handle);
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = efi_call_early(locate_handle,
|
||||
EFI_LOCATE_BY_PROTOCOL,
|
||||
proto, NULL, &size, gop_handle);
|
||||
status = efi_bs_call(locate_handle, EFI_LOCATE_BY_PROTOCOL, proto, NULL,
|
||||
&size, gop_handle);
|
||||
if (status != EFI_SUCCESS)
|
||||
goto free_handle;
|
||||
|
||||
if (efi_is_64bit()) {
|
||||
status = setup_gop64(sys_table_arg, si, proto, size,
|
||||
gop_handle);
|
||||
} else {
|
||||
status = setup_gop32(sys_table_arg, si, proto, size,
|
||||
gop_handle);
|
||||
}
|
||||
status = setup_gop(si, proto, size, gop_handle);
|
||||
|
||||
free_handle:
|
||||
efi_call_early(free_pool, gop_handle);
|
||||
efi_bs_call(free_pool, gop_handle);
|
||||
return status;
|
||||
}
|
||||
|
114
drivers/firmware/efi/libstub/pci.c
Normal file
114
drivers/firmware/efi/libstub/pci.c
Normal file
@@ -0,0 +1,114 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* PCI-related functions used by the EFI stub on multiple
|
||||
* architectures.
|
||||
*
|
||||
* Copyright 2019 Google, LLC
|
||||
*/
|
||||
|
||||
#include <linux/efi.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <asm/efi.h>
|
||||
|
||||
#include "efistub.h"
|
||||
|
||||
void efi_pci_disable_bridge_busmaster(void)
|
||||
{
|
||||
efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
|
||||
unsigned long pci_handle_size = 0;
|
||||
efi_handle_t *pci_handle = NULL;
|
||||
efi_handle_t handle;
|
||||
efi_status_t status;
|
||||
u16 class, command;
|
||||
int i;
|
||||
|
||||
status = efi_bs_call(locate_handle, EFI_LOCATE_BY_PROTOCOL, &pci_proto,
|
||||
NULL, &pci_handle_size, NULL);
|
||||
|
||||
if (status != EFI_BUFFER_TOO_SMALL) {
|
||||
if (status != EFI_SUCCESS && status != EFI_NOT_FOUND)
|
||||
pr_efi_err("Failed to locate PCI I/O handles'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, pci_handle_size,
|
||||
(void **)&pci_handle);
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err("Failed to allocate memory for 'pci_handle'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
status = efi_bs_call(locate_handle, EFI_LOCATE_BY_PROTOCOL, &pci_proto,
|
||||
NULL, &pci_handle_size, pci_handle);
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_efi_err("Failed to locate PCI I/O handles'\n");
|
||||
goto free_handle;
|
||||
}
|
||||
|
||||
for_each_efi_handle(handle, pci_handle, pci_handle_size, i) {
|
||||
efi_pci_io_protocol_t *pci;
|
||||
unsigned long segment_nr, bus_nr, device_nr, func_nr;
|
||||
|
||||
status = efi_bs_call(handle_protocol, handle, &pci_proto,
|
||||
(void **)&pci);
|
||||
if (status != EFI_SUCCESS)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Disregard devices living on bus 0 - these are not behind a
|
||||
* bridge so no point in disconnecting them from their drivers.
|
||||
*/
|
||||
status = efi_call_proto(pci, get_location, &segment_nr, &bus_nr,
|
||||
&device_nr, &func_nr);
|
||||
if (status != EFI_SUCCESS || bus_nr == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Don't disconnect VGA controllers so we don't risk losing
|
||||
* access to the framebuffer. Drivers for true PCIe graphics
|
||||
* controllers that are behind a PCIe root port do not use
|
||||
* DMA to implement the GOP framebuffer anyway [although they
|
||||
* may use it in their implentation of Gop->Blt()], and so
|
||||
* disabling DMA in the PCI bridge should not interfere with
|
||||
* normal operation of the device.
|
||||
*/
|
||||
status = efi_call_proto(pci, pci.read, EfiPciIoWidthUint16,
|
||||
PCI_CLASS_DEVICE, 1, &class);
|
||||
if (status != EFI_SUCCESS || class == PCI_CLASS_DISPLAY_VGA)
|
||||
continue;
|
||||
|
||||
/* Disconnect this handle from all its drivers */
|
||||
efi_bs_call(disconnect_controller, handle, NULL, NULL);
|
||||
}
|
||||
|
||||
for_each_efi_handle(handle, pci_handle, pci_handle_size, i) {
|
||||
efi_pci_io_protocol_t *pci;
|
||||
|
||||
status = efi_bs_call(handle_protocol, handle, &pci_proto,
|
||||
(void **)&pci);
|
||||
if (status != EFI_SUCCESS || !pci)
|
||||
continue;
|
||||
|
||||
status = efi_call_proto(pci, pci.read, EfiPciIoWidthUint16,
|
||||
PCI_CLASS_DEVICE, 1, &class);
|
||||
|
||||
if (status != EFI_SUCCESS || class != PCI_CLASS_BRIDGE_PCI)
|
||||
continue;
|
||||
|
||||
/* Disable busmastering */
|
||||
status = efi_call_proto(pci, pci.read, EfiPciIoWidthUint16,
|
||||
PCI_COMMAND, 1, &command);
|
||||
if (status != EFI_SUCCESS || !(command & PCI_COMMAND_MASTER))
|
||||
continue;
|
||||
|
||||
command &= ~PCI_COMMAND_MASTER;
|
||||
status = efi_call_proto(pci, pci.write, EfiPciIoWidthUint16,
|
||||
PCI_COMMAND, 1, &command);
|
||||
if (status != EFI_SUCCESS)
|
||||
pr_efi_err("Failed to disable PCI busmastering\n");
|
||||
}
|
||||
|
||||
free_handle:
|
||||
efi_bs_call(free_pool, pci_handle);
|
||||
}
|
@@ -9,38 +9,34 @@
|
||||
|
||||
#include "efistub.h"
|
||||
|
||||
typedef struct efi_rng_protocol efi_rng_protocol_t;
|
||||
typedef union efi_rng_protocol efi_rng_protocol_t;
|
||||
|
||||
typedef struct {
|
||||
u32 get_info;
|
||||
u32 get_rng;
|
||||
} efi_rng_protocol_32_t;
|
||||
|
||||
typedef struct {
|
||||
u64 get_info;
|
||||
u64 get_rng;
|
||||
} efi_rng_protocol_64_t;
|
||||
|
||||
struct efi_rng_protocol {
|
||||
efi_status_t (*get_info)(struct efi_rng_protocol *,
|
||||
unsigned long *, efi_guid_t *);
|
||||
efi_status_t (*get_rng)(struct efi_rng_protocol *,
|
||||
efi_guid_t *, unsigned long, u8 *out);
|
||||
union efi_rng_protocol {
|
||||
struct {
|
||||
efi_status_t (__efiapi *get_info)(efi_rng_protocol_t *,
|
||||
unsigned long *,
|
||||
efi_guid_t *);
|
||||
efi_status_t (__efiapi *get_rng)(efi_rng_protocol_t *,
|
||||
efi_guid_t *, unsigned long,
|
||||
u8 *out);
|
||||
};
|
||||
struct {
|
||||
u32 get_info;
|
||||
u32 get_rng;
|
||||
} mixed_mode;
|
||||
};
|
||||
|
||||
efi_status_t efi_get_random_bytes(efi_system_table_t *sys_table_arg,
|
||||
unsigned long size, u8 *out)
|
||||
efi_status_t efi_get_random_bytes(unsigned long size, u8 *out)
|
||||
{
|
||||
efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
|
||||
efi_status_t status;
|
||||
struct efi_rng_protocol *rng = NULL;
|
||||
efi_rng_protocol_t *rng = NULL;
|
||||
|
||||
status = efi_call_early(locate_protocol, &rng_proto, NULL,
|
||||
(void **)&rng);
|
||||
status = efi_bs_call(locate_protocol, &rng_proto, NULL, (void **)&rng);
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
|
||||
return efi_call_proto(efi_rng_protocol, get_rng, rng, NULL, size, out);
|
||||
return efi_call_proto(rng, get_rng, NULL, size, out);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -81,8 +77,7 @@ static unsigned long get_entry_num_slots(efi_memory_desc_t *md,
|
||||
*/
|
||||
#define MD_NUM_SLOTS(md) ((md)->virt_addr)
|
||||
|
||||
efi_status_t efi_random_alloc(efi_system_table_t *sys_table_arg,
|
||||
unsigned long size,
|
||||
efi_status_t efi_random_alloc(unsigned long size,
|
||||
unsigned long align,
|
||||
unsigned long *addr,
|
||||
unsigned long random_seed)
|
||||
@@ -101,7 +96,7 @@ efi_status_t efi_random_alloc(efi_system_table_t *sys_table_arg,
|
||||
map.key_ptr = NULL;
|
||||
map.buff_size = &buff_size;
|
||||
|
||||
status = efi_get_memory_map(sys_table_arg, &map);
|
||||
status = efi_get_memory_map(&map);
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
|
||||
@@ -145,39 +140,38 @@ efi_status_t efi_random_alloc(efi_system_table_t *sys_table_arg,
|
||||
target = round_up(md->phys_addr, align) + target_slot * align;
|
||||
pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
|
||||
|
||||
status = efi_call_early(allocate_pages, EFI_ALLOCATE_ADDRESS,
|
||||
EFI_LOADER_DATA, pages, &target);
|
||||
status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS,
|
||||
EFI_LOADER_DATA, pages, &target);
|
||||
if (status == EFI_SUCCESS)
|
||||
*addr = target;
|
||||
break;
|
||||
}
|
||||
|
||||
efi_call_early(free_pool, memory_map);
|
||||
efi_bs_call(free_pool, memory_map);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg)
|
||||
efi_status_t efi_random_get_seed(void)
|
||||
{
|
||||
efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
|
||||
efi_guid_t rng_algo_raw = EFI_RNG_ALGORITHM_RAW;
|
||||
efi_guid_t rng_table_guid = LINUX_EFI_RANDOM_SEED_TABLE_GUID;
|
||||
struct efi_rng_protocol *rng = NULL;
|
||||
efi_rng_protocol_t *rng = NULL;
|
||||
struct linux_efi_random_seed *seed = NULL;
|
||||
efi_status_t status;
|
||||
|
||||
status = efi_call_early(locate_protocol, &rng_proto, NULL,
|
||||
(void **)&rng);
|
||||
status = efi_bs_call(locate_protocol, &rng_proto, NULL, (void **)&rng);
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = efi_call_early(allocate_pool, EFI_RUNTIME_SERVICES_DATA,
|
||||
sizeof(*seed) + EFI_RANDOM_SEED_SIZE,
|
||||
(void **)&seed);
|
||||
status = efi_bs_call(allocate_pool, EFI_RUNTIME_SERVICES_DATA,
|
||||
sizeof(*seed) + EFI_RANDOM_SEED_SIZE,
|
||||
(void **)&seed);
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = efi_call_proto(efi_rng_protocol, get_rng, rng, &rng_algo_raw,
|
||||
status = efi_call_proto(rng, get_rng, &rng_algo_raw,
|
||||
EFI_RANDOM_SEED_SIZE, seed->bits);
|
||||
|
||||
if (status == EFI_UNSUPPORTED)
|
||||
@@ -185,21 +179,20 @@ efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg)
|
||||
* Use whatever algorithm we have available if the raw algorithm
|
||||
* is not implemented.
|
||||
*/
|
||||
status = efi_call_proto(efi_rng_protocol, get_rng, rng, NULL,
|
||||
EFI_RANDOM_SEED_SIZE, seed->bits);
|
||||
status = efi_call_proto(rng, get_rng, NULL,
|
||||
EFI_RANDOM_SEED_SIZE, seed->bits);
|
||||
|
||||
if (status != EFI_SUCCESS)
|
||||
goto err_freepool;
|
||||
|
||||
seed->size = EFI_RANDOM_SEED_SIZE;
|
||||
status = efi_call_early(install_configuration_table, &rng_table_guid,
|
||||
seed);
|
||||
status = efi_bs_call(install_configuration_table, &rng_table_guid, seed);
|
||||
if (status != EFI_SUCCESS)
|
||||
goto err_freepool;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
err_freepool:
|
||||
efi_call_early(free_pool, seed);
|
||||
efi_bs_call(free_pool, seed);
|
||||
return status;
|
||||
}
|
||||
|
@@ -21,18 +21,13 @@ static const efi_char16_t efi_SetupMode_name[] = L"SetupMode";
|
||||
static const efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID;
|
||||
static const efi_char16_t shim_MokSBState_name[] = L"MokSBState";
|
||||
|
||||
#define get_efi_var(name, vendor, ...) \
|
||||
efi_call_runtime(get_variable, \
|
||||
(efi_char16_t *)(name), (efi_guid_t *)(vendor), \
|
||||
__VA_ARGS__);
|
||||
|
||||
/*
|
||||
* Determine whether we're in secure boot mode.
|
||||
*
|
||||
* Please keep the logic in sync with
|
||||
* arch/x86/xen/efi.c:xen_efi_get_secureboot().
|
||||
*/
|
||||
enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table_arg)
|
||||
enum efi_secureboot_mode efi_get_secureboot(void)
|
||||
{
|
||||
u32 attr;
|
||||
u8 secboot, setupmode, moksbstate;
|
||||
@@ -72,10 +67,10 @@ enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table_arg)
|
||||
return efi_secureboot_mode_disabled;
|
||||
|
||||
secure_boot_enabled:
|
||||
pr_efi(sys_table_arg, "UEFI Secure Boot is enabled.\n");
|
||||
pr_efi("UEFI Secure Boot is enabled.\n");
|
||||
return efi_secureboot_mode_enabled;
|
||||
|
||||
out_efi_err:
|
||||
pr_efi_err(sys_table_arg, "Could not determine UEFI Secure Boot status.\n");
|
||||
pr_efi_err("Could not determine UEFI Secure Boot status.\n");
|
||||
return efi_secureboot_mode_unknown;
|
||||
}
|
||||
|
@@ -20,23 +20,13 @@ static const efi_char16_t efi_MemoryOverWriteRequest_name[] =
|
||||
#define MEMORY_ONLY_RESET_CONTROL_GUID \
|
||||
EFI_GUID(0xe20939be, 0x32d4, 0x41be, 0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29)
|
||||
|
||||
#define get_efi_var(name, vendor, ...) \
|
||||
efi_call_runtime(get_variable, \
|
||||
(efi_char16_t *)(name), (efi_guid_t *)(vendor), \
|
||||
__VA_ARGS__)
|
||||
|
||||
#define set_efi_var(name, vendor, ...) \
|
||||
efi_call_runtime(set_variable, \
|
||||
(efi_char16_t *)(name), (efi_guid_t *)(vendor), \
|
||||
__VA_ARGS__)
|
||||
|
||||
/*
|
||||
* Enable reboot attack mitigation. This requests that the firmware clear the
|
||||
* RAM on next reboot before proceeding with boot, ensuring that any secrets
|
||||
* are cleared. If userland has ensured that all secrets have been removed
|
||||
* from RAM before reboot it can simply reset this variable.
|
||||
*/
|
||||
void efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg)
|
||||
void efi_enable_reset_attack_mitigation(void)
|
||||
{
|
||||
u8 val = 1;
|
||||
efi_guid_t var_guid = MEMORY_ONLY_RESET_CONTROL_GUID;
|
||||
@@ -57,7 +47,7 @@ void efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg)
|
||||
|
||||
#endif
|
||||
|
||||
void efi_retrieve_tpm2_eventlog(efi_system_table_t *sys_table_arg)
|
||||
void efi_retrieve_tpm2_eventlog(void)
|
||||
{
|
||||
efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID;
|
||||
efi_guid_t linux_eventlog_guid = LINUX_EFI_TPM_EVENT_LOG_GUID;
|
||||
@@ -69,23 +59,22 @@ void efi_retrieve_tpm2_eventlog(efi_system_table_t *sys_table_arg)
|
||||
size_t log_size, last_entry_size;
|
||||
efi_bool_t truncated;
|
||||
int version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
|
||||
void *tcg2_protocol = NULL;
|
||||
efi_tcg2_protocol_t *tcg2_protocol = NULL;
|
||||
int final_events_size = 0;
|
||||
|
||||
status = efi_call_early(locate_protocol, &tcg2_guid, NULL,
|
||||
&tcg2_protocol);
|
||||
status = efi_bs_call(locate_protocol, &tcg2_guid, NULL,
|
||||
(void **)&tcg2_protocol);
|
||||
if (status != EFI_SUCCESS)
|
||||
return;
|
||||
|
||||
status = efi_call_proto(efi_tcg2_protocol, get_event_log,
|
||||
tcg2_protocol, version, &log_location,
|
||||
&log_last_entry, &truncated);
|
||||
status = efi_call_proto(tcg2_protocol, get_event_log, version,
|
||||
&log_location, &log_last_entry, &truncated);
|
||||
|
||||
if (status != EFI_SUCCESS || !log_location) {
|
||||
version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
|
||||
status = efi_call_proto(efi_tcg2_protocol, get_event_log,
|
||||
tcg2_protocol, version, &log_location,
|
||||
&log_last_entry, &truncated);
|
||||
status = efi_call_proto(tcg2_protocol, get_event_log, version,
|
||||
&log_location, &log_last_entry,
|
||||
&truncated);
|
||||
if (status != EFI_SUCCESS || !log_location)
|
||||
return;
|
||||
|
||||
@@ -126,13 +115,11 @@ void efi_retrieve_tpm2_eventlog(efi_system_table_t *sys_table_arg)
|
||||
}
|
||||
|
||||
/* Allocate space for the logs and copy them. */
|
||||
status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
|
||||
sizeof(*log_tbl) + log_size,
|
||||
(void **) &log_tbl);
|
||||
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA,
|
||||
sizeof(*log_tbl) + log_size, (void **)&log_tbl);
|
||||
|
||||
if (status != EFI_SUCCESS) {
|
||||
efi_printk(sys_table_arg,
|
||||
"Unable to allocate memory for event log\n");
|
||||
efi_printk("Unable to allocate memory for event log\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -140,8 +127,7 @@ void efi_retrieve_tpm2_eventlog(efi_system_table_t *sys_table_arg)
|
||||
* Figure out whether any events have already been logged to the
|
||||
* final events structure, and if so how much space they take up
|
||||
*/
|
||||
final_events_table = get_efi_config_table(sys_table_arg,
|
||||
LINUX_EFI_TPM_FINAL_LOG_GUID);
|
||||
final_events_table = get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID);
|
||||
if (final_events_table && final_events_table->nr_events) {
|
||||
struct tcg_pcr_event2_head *header;
|
||||
int offset;
|
||||
@@ -169,12 +155,12 @@ void efi_retrieve_tpm2_eventlog(efi_system_table_t *sys_table_arg)
|
||||
log_tbl->version = version;
|
||||
memcpy(log_tbl->log, (void *) first_entry_addr, log_size);
|
||||
|
||||
status = efi_call_early(install_configuration_table,
|
||||
&linux_eventlog_guid, log_tbl);
|
||||
status = efi_bs_call(install_configuration_table,
|
||||
&linux_eventlog_guid, log_tbl);
|
||||
if (status != EFI_SUCCESS)
|
||||
goto err_free;
|
||||
return;
|
||||
|
||||
err_free:
|
||||
efi_call_early(free_pool, log_tbl);
|
||||
efi_bs_call(free_pool, log_tbl);
|
||||
}
|
||||
|
Reference in New Issue
Block a user