diff options
author | Tom Rini <trini@konsulko.com> | 2022-01-15 07:39:09 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-01-15 07:39:09 -0500 |
commit | d71dbe657c3c22f50ecb3df133e5cdd884daae7d (patch) | |
tree | a7c4e1c7c88dfc3a06e5cea82570c7214988c6cc /lib | |
parent | 0962da92a1dfb210eef8c936e33862812fa1b208 (diff) | |
parent | 6b3873c5eaf6486db086df51d4cd61a933668f7b (diff) | |
download | u-boot-d71dbe657c3c22f50ecb3df133e5cdd884daae7d.tar.gz |
Merge tag 'efi-2022-04-rc1' of https://source.denx.de/u-boot/custodians/u-boot-efiWIP/15Jan2022
Pull request for efi-2022-04-rc1
Documentation:
* Fix building HTML documentation of readthedocs.io
* Add ARM Juno board documentation
* Build requirements for Alpine Linux
* Include DM headers in API documentation
UEFI:
* Fix section alignment of EFI binaries
* Fix header length of RISC-V EFI binaries allowing to run them on EDK II
* Remove kaslr-seed from device tree if the EFI_RNG_PROTOCOL is provided
Other:
* Let 'part list' show all 128 GPT partitions
Diffstat (limited to 'lib')
-rw-r--r-- | lib/efi/efi.c | 72 | ||||
-rw-r--r-- | lib/efi/efi_app.c | 42 | ||||
-rw-r--r-- | lib/efi/efi_stub.c | 66 | ||||
-rw-r--r-- | lib/efi_loader/efi_dt_fixup.c | 33 | ||||
-rw-r--r-- | lib/efi_loader/efi_firmware.c | 7 |
5 files changed, 163 insertions, 57 deletions
diff --git a/lib/efi/efi.c b/lib/efi/efi.c index cd6bf47b180..aa42f1842f3 100644 --- a/lib/efi/efi.c +++ b/lib/efi/efi.c @@ -135,3 +135,75 @@ void efi_free(struct efi_priv *priv, void *ptr) boot->free_pool(ptr); } + +int efi_store_memory_map(struct efi_priv *priv) +{ + struct efi_boot_services *boot = priv->sys_table->boottime; + efi_uintn_t size, desc_size; + efi_status_t ret; + + /* Get the memory map so we can switch off EFI */ + size = 0; + ret = boot->get_memory_map(&size, NULL, &priv->memmap_key, + &priv->memmap_desc_size, + &priv->memmap_version); + if (ret != EFI_BUFFER_TOO_SMALL) { + /* + * Note this function avoids using printf() since it is not + * available in the stub + */ + printhex2(EFI_BITS_PER_LONG); + putc(' '); + printhex2(ret); + puts(" No memory map\n"); + return ret; + } + /* + * Since doing a malloc() may change the memory map and also we want to + * be able to read the memory map in efi_call_exit_boot_services() + * below, after more changes have happened + */ + priv->memmap_alloc = size + 1024; + priv->memmap_size = priv->memmap_alloc; + priv->memmap_desc = efi_malloc(priv, size, &ret); + if (!priv->memmap_desc) { + printhex2(ret); + puts(" No memory for memory descriptor\n"); + return ret; + } + + ret = boot->get_memory_map(&priv->memmap_size, priv->memmap_desc, + &priv->memmap_key, &desc_size, + &priv->memmap_version); + if (ret) { + printhex2(ret); + puts(" Can't get memory map\n"); + return ret; + } + + return 0; +} + +int efi_call_exit_boot_services(void) +{ + struct efi_priv *priv = efi_get_priv(); + const struct efi_boot_services *boot = priv->boot; + efi_uintn_t size; + u32 version; + efi_status_t ret; + + size = priv->memmap_alloc; + ret = boot->get_memory_map(&size, priv->memmap_desc, + &priv->memmap_key, + &priv->memmap_desc_size, &version); + if (ret) { + printhex2(ret); + puts(" Can't get memory map\n"); + return ret; + } + ret = boot->exit_boot_services(priv->parent_image, priv->memmap_key); + if (ret) + return ret; + + return 0; +} diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c index d60f2f6c28f..6980933d7ea 100644 --- a/lib/efi/efi_app.c +++ b/lib/efi/efi_app.c @@ -32,6 +32,39 @@ int efi_info_get(enum efi_entry_t type, void **datap, int *sizep) return -ENOSYS; } +int efi_get_mmap(struct efi_mem_desc **descp, int *sizep, uint *keyp, + int *desc_sizep, uint *versionp) +{ + struct efi_priv *priv = efi_get_priv(); + struct efi_boot_services *boot = priv->sys_table->boottime; + efi_uintn_t size, desc_size, key; + struct efi_mem_desc *desc; + efi_status_t ret; + u32 version; + + /* Get the memory map so we can switch off EFI */ + size = 0; + ret = boot->get_memory_map(&size, NULL, &key, &desc_size, &version); + if (ret != EFI_BUFFER_TOO_SMALL) + return log_msg_ret("get", -ENOMEM); + + desc = malloc(size); + if (!desc) + return log_msg_ret("mem", -ENOMEM); + + ret = boot->get_memory_map(&size, desc, &key, &desc_size, &version); + if (ret) + return log_msg_ret("get", -EINVAL); + + *descp = desc; + *sizep = size; + *desc_sizep = desc_size; + *versionp = version; + *keyp = key; + + return 0; +} + /** * efi_bind_block() - bind a new block device to an EFI device * @@ -321,6 +354,15 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, return ret; } + /* + * We could store the EFI memory map here, but it changes all the time, + * so this is only useful for debugging. + * + * ret = efi_store_memory_map(priv); + * if (ret) + * return ret; + */ + printf("starting\n"); board_init_f(GD_FLG_SKIP_RELOC); diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c index c89ae7c9072..646cde3214c 100644 --- a/lib/efi/efi_stub.c +++ b/lib/efi/efi_stub.c @@ -304,15 +304,12 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, { struct efi_priv local_priv, *priv = &local_priv; struct efi_boot_services *boot = sys_table->boottime; - struct efi_mem_desc *desc; struct efi_entry_memmap map; struct efi_gop *gop; struct efi_entry_gopmode mode; struct efi_entry_systable table; efi_guid_t efi_gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; - efi_uintn_t key, desc_size, size; efi_status_t ret; - u32 version; int cs32; ret = efi_init(priv, "Payload", image, sys_table); @@ -327,24 +324,11 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, if (cs32 < 0) return EFI_UNSUPPORTED; - /* Get the memory map so we can switch off EFI */ - size = 0; - ret = boot->get_memory_map(&size, NULL, &key, &desc_size, &version); - if (ret != EFI_BUFFER_TOO_SMALL) { - printhex2(EFI_BITS_PER_LONG); - putc(' '); - printhex2(ret); - puts(" No memory map\n"); - return ret; - } - size += 1024; /* Since doing a malloc() may change the memory map! */ - desc = efi_malloc(priv, size, &ret); - if (!desc) { - printhex2(ret); - puts(" No memory for memory descriptor\n"); + ret = efi_store_memory_map(priv); + if (ret) return ret; - } - ret = setup_info_table(priv, size + 128); + + ret = setup_info_table(priv, priv->memmap_size + 128); if (ret) return ret; @@ -360,48 +344,20 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, sizeof(struct efi_gop_mode_info)); } - ret = boot->get_memory_map(&size, desc, &key, &desc_size, &version); - if (ret) { - printhex2(ret); - puts(" Can't get memory map\n"); - return ret; - } - table.sys_table = (ulong)sys_table; add_entry_addr(priv, EFIET_SYS_TABLE, &table, sizeof(table), NULL, 0); - ret = boot->exit_boot_services(image, key); - if (ret) { - /* - * Unfortunately it happens that we cannot exit boot services - * the first time. But the second time it work. I don't know - * why but this seems to be a repeatable problem. To get - * around it, just try again. - */ - printhex2(ret); - puts(" Can't exit boot services\n"); - size = sizeof(desc); - ret = boot->get_memory_map(&size, desc, &key, &desc_size, - &version); - if (ret) { - printhex2(ret); - puts(" Can't get memory map\n"); - return ret; - } - ret = boot->exit_boot_services(image, key); - if (ret) { - printhex2(ret); - puts(" Can't exit boot services 2\n"); - return ret; - } - } + ret = efi_call_exit_boot_services(); + if (ret) + return ret; /* The EFI UART won't work now, switch to a debug one */ use_uart = true; - map.version = version; - map.desc_size = desc_size; - add_entry_addr(priv, EFIET_MEMORY_MAP, &map, sizeof(map), desc, size); + map.version = priv->memmap_version; + map.desc_size = priv->memmap_desc_size; + add_entry_addr(priv, EFIET_MEMORY_MAP, &map, sizeof(map), + priv->memmap_desc, priv->memmap_size); add_entry_addr(priv, EFIET_END, NULL, 0, 0, 0); memcpy((void *)CONFIG_SYS_TEXT_BASE, _binary_u_boot_bin_start, diff --git a/lib/efi_loader/efi_dt_fixup.c b/lib/efi_loader/efi_dt_fixup.c index b6fe5d2e5a3..d3923e5dba1 100644 --- a/lib/efi_loader/efi_dt_fixup.c +++ b/lib/efi_loader/efi_dt_fixup.c @@ -8,6 +8,7 @@ #include <common.h> #include <efi_dt_fixup.h> #include <efi_loader.h> +#include <efi_rng.h> #include <fdtdec.h> #include <mapmem.h> @@ -41,6 +42,38 @@ static void efi_reserve_memory(u64 addr, u64 size, bool nomap) } /** + * efi_try_purge_kaslr_seed() - Remove unused kaslr-seed + * + * Kernel's EFI STUB only relies on EFI_RNG_PROTOCOL for randomization + * and completely ignores the kaslr-seed for its own randomness needs + * (i.e the randomization of the physical placement of the kernel). + * Weed it out from the DTB we hand over, which would mess up our DTB + * TPM measurements as well. + * + * @fdt: Pointer to device tree + */ +void efi_try_purge_kaslr_seed(void *fdt) +{ + const efi_guid_t efi_guid_rng_protocol = EFI_RNG_PROTOCOL_GUID; + struct efi_handler *handler; + efi_status_t ret; + int nodeoff = 0; + int err = 0; + + ret = efi_search_protocol(efi_root, &efi_guid_rng_protocol, &handler); + if (ret != EFI_SUCCESS) + return; + + nodeoff = fdt_path_offset(fdt, "/chosen"); + if (nodeoff < 0) + return; + + err = fdt_delprop(fdt, nodeoff, "kaslr-seed"); + if (err < 0 && err != -FDT_ERR_NOTFOUND) + log_err("Error deleting kaslr-seed\n"); +} + +/** * efi_carve_out_dt_rsv() - Carve out DT reserved memory ranges * * The mem_rsv entries of the FDT are added to the memory map. Any failures are diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index a1b88dbfc28..519a47267ca 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -128,8 +128,11 @@ static efi_status_t efi_get_dfu_info( size_t names_len, total_size; int dfu_num, i; u16 *name, *next; + int ret; - dfu_init_env_entities(NULL, NULL); + ret = dfu_init_env_entities(NULL, NULL); + if (ret) + return EFI_SUCCESS; names_len = 0; dfu_num = 0; @@ -138,7 +141,7 @@ static efi_status_t efi_get_dfu_info( dfu_num++; } if (!dfu_num) { - log_warning("Probably dfu_alt_info not defined\n"); + log_warning("No entities in dfu_alt_info\n"); *image_info_size = 0; dfu_free_entities(); |