From 796933510f84c1a29b1ef104d0962db6c0b7589c Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 27 Sep 2020 14:50:25 +0200 Subject: efi_loader: efidebug display RNG protocol Add the Random Number Generator (RNG) protocol to the GUIDs that the 'efidebug dh' protocol can replace by a text. Signed-off-by: Heinrich Schuchardt --- cmd/efidebug.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmd/efidebug.c b/cmd/efidebug.c index 9874838b00..5288b9920b 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -248,6 +249,10 @@ static const struct { "Load File2", EFI_LOAD_FILE2_PROTOCOL_GUID, }, + { + "Random Number Generator", + EFI_RNG_PROTOCOL_GUID, + }, { "Simple Network", EFI_SIMPLE_NETWORK_PROTOCOL_GUID, -- cgit From b59c13d42f42811912fd08f32f11e68a8e708c00 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 25 Sep 2020 12:50:19 +0200 Subject: efi_loader: installation of EFI_RNG_PROTOCOL Having an EFI_RNG_PROTOCOL without a backing RNG device leads to failure to boot Linux 5.8. Only install the EFI_RNG_PROTOCOL if we have a RNG device. Reported-by: Scott K Logan Cc: Neil Armstrong Cc: Ard Biesheuvel Signed-off-by: Heinrich Schuchardt --- include/efi_loader.h | 3 ++- lib/efi_loader/efi_rng.c | 30 +++++++++++++++++++++++++++++- lib/efi_loader/efi_root_node.c | 4 ---- lib/efi_loader/efi_setup.c | 5 +++++ 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index 0baa1d2324..7eea5566fd 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -154,7 +154,6 @@ extern const struct efi_hii_config_routing_protocol efi_hii_config_routing; extern const struct efi_hii_config_access_protocol efi_hii_config_access; extern const struct efi_hii_database_protocol efi_hii_database; extern const struct efi_hii_string_protocol efi_hii_string; -extern const struct efi_rng_protocol efi_rng_protocol; uint16_t *efi_dp_str(struct efi_device_path *dp); @@ -404,6 +403,8 @@ efi_status_t EFIAPI efi_convert_pointer(efi_uintn_t debug_disposition, efi_status_t efi_console_register(void); /* Called by bootefi to make all disk storage accessible as EFI objects */ efi_status_t efi_disk_register(void); +/* Called by efi_init_obj_list() to install EFI_RNG_PROTOCOL */ +efi_status_t efi_rng_register(void); /* Create handles and protocols for the partitions of a block device */ int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc, const char *if_typename, int diskid, diff --git a/lib/efi_loader/efi_rng.c b/lib/efi_loader/efi_rng.c index caef4085b0..a8a87007b6 100644 --- a/lib/efi_loader/efi_rng.c +++ b/lib/efi_loader/efi_rng.c @@ -3,6 +3,8 @@ * Copyright (c) 2019, Linaro Limited */ +#define LOG_CATEGORY LOGC_EFI + #include #include #include @@ -144,7 +146,33 @@ back: return EFI_EXIT(status); } -const struct efi_rng_protocol efi_rng_protocol = { +static const struct efi_rng_protocol efi_rng_protocol = { .get_info = rng_getinfo, .get_rng = getrng, }; + +/** + * efi_rng_register() - register EFI_RNG_PROTOCOL + * + * If a RNG device is available, the Random Number Generator Protocol is + * registered. + * + * Return: An error status is only returned if adding the protocol fails. + */ +efi_status_t efi_rng_register(void) +{ + efi_status_t ret; + struct udevice *dev; + + ret = platform_get_rng_device(&dev); + if (ret != EFI_SUCCESS) { + log_warning("Missing RNG device for EFI_RNG_PROTOCOL"); + return EFI_SUCCESS; + } + ret = efi_add_protocol(efi_root, &efi_guid_rng_protocol, + (void *)&efi_rng_protocol); + if (ret != EFI_SUCCESS) + log_err("Cannot install EFI_RNG_PROTOCOL"); + + return ret; +} diff --git a/lib/efi_loader/efi_root_node.c b/lib/efi_loader/efi_root_node.c index 76d18fb1a4..f68b0fdc61 100644 --- a/lib/efi_loader/efi_root_node.c +++ b/lib/efi_loader/efi_root_node.c @@ -80,10 +80,6 @@ efi_status_t efi_root_node_register(void) /* HII configuration routing protocol */ &efi_guid_hii_config_routing_protocol, (void *)&efi_hii_config_routing, -#endif -#if CONFIG_IS_ENABLED(EFI_RNG_PROTOCOL) - &efi_guid_rng_protocol, - (void *)&efi_rng_protocol, #endif NULL)); efi_root->type = EFI_OBJECT_TYPE_U_BOOT_FIRMWARE; diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index 6196c0a06c..45226c5c1a 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -151,6 +151,11 @@ efi_status_t efi_init_obj_list(void) if (ret != EFI_SUCCESS) goto out; #endif + if (IS_ENABLED(CONFIG_EFI_RNG_PROTOCOL)) { + ret = efi_rng_register(); + if (ret != EFI_SUCCESS) + goto out; + } /* Initialize variable services */ ret = efi_init_variables(); if (ret != EFI_SUCCESS) -- cgit From c48e9f310b950e39a91cea74b6708dd4fe2eb39c Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 26 Sep 2020 07:50:36 +0200 Subject: riscv: restore global data pointer in trap handler The gp register is used to store U-Boot's global data pointer. We should not assume that an UEFI application leaves the gp register unchanged as the UEFI specifications does not define who is the owner of the gp and tp registers. So the following sequence should be followed in the trap handler: * save the caller's gp register * restore the global data pointer * serve interrupts or print crash dump and reset * restore the caller's gp register Cc: Abner Chang Signed-off-by: Heinrich Schuchardt Reviewed-by: Bin Meng Reviewed-by: Rick Chen --- arch/riscv/lib/interrupts.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c index cd47e64487..8ff40f0f36 100644 --- a/arch/riscv/lib/interrupts.c +++ b/arch/riscv/lib/interrupts.c @@ -111,6 +111,9 @@ ulong handle_trap(ulong cause, ulong epc, ulong tval, struct pt_regs *regs) { ulong is_irq, irq; + /* An UEFI application may have changed gd. Restore U-Boot's gd. */ + efi_restore_gd(); + is_irq = (cause & MCAUSE_INT); irq = (cause & ~MCAUSE_INT); -- cgit