summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2022-01-15 07:39:09 -0500
committerTom Rini <trini@konsulko.com>2022-01-15 07:39:09 -0500
commitd71dbe657c3c22f50ecb3df133e5cdd884daae7d (patch)
treea7c4e1c7c88dfc3a06e5cea82570c7214988c6cc /lib
parent0962da92a1dfb210eef8c936e33862812fa1b208 (diff)
parent6b3873c5eaf6486db086df51d4cd61a933668f7b (diff)
Merge tag 'efi-2022-04-rc1' of https://source.denx.de/u-boot/custodians/u-boot-efi
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.c72
-rw-r--r--lib/efi/efi_app.c42
-rw-r--r--lib/efi/efi_stub.c66
-rw-r--r--lib/efi_loader/efi_dt_fixup.c33
-rw-r--r--lib/efi_loader/efi_firmware.c7
5 files changed, 163 insertions, 57 deletions
diff --git a/lib/efi/efi.c b/lib/efi/efi.c
index cd6bf47b18..aa42f1842f 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 d60f2f6c28..6980933d7e 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 c89ae7c907..646cde3214 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 b6fe5d2e5a..d3923e5dba 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 a1b88dbfc2..519a47267c 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();