diff options
author | Tom Rini <trini@konsulko.com> | 2021-07-02 15:04:07 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-07-02 15:04:07 -0400 |
commit | 62c7e40a04c8c78615060073942e2e48f722c22b (patch) | |
tree | 3ee01b254834bcb7c102197f4b49e083ecc7b471 | |
parent | 760d2f9e9e66c7eacfbcff21dcd3733d16526438 (diff) | |
parent | 0fa5020c024e49222ca97ead3502b332d35dea76 (diff) | |
download | u-boot-62c7e40a04c8c78615060073942e2e48f722c22b.zip u-boot-62c7e40a04c8c78615060073942e2e48f722c22b.tar.gz u-boot-62c7e40a04c8c78615060073942e2e48f722c22b.tar.bz2 |
Merge tag 'efi-2021-07-rc6' of https://source.denx.de/u-boot/custodians/u-boot-efiWIP/02Jul2021
Pull request for efi-2021-07-rc6
Bug fixes:
* improve specification compliance of UEFI capsule updates
* allow capsule update on-disk without checking OsIndications
* provide parameter checks for QueryVariableInfo()
-rw-r--r-- | configs/xilinx_zynqmp_virt_defconfig | 1 | ||||
-rw-r--r-- | include/efi_loader.h | 1 | ||||
-rw-r--r-- | lib/efi_loader/Kconfig | 55 | ||||
-rw-r--r-- | lib/efi_loader/efi_capsule.c | 49 | ||||
-rw-r--r-- | lib/efi_loader/efi_console.c | 2 | ||||
-rw-r--r-- | lib/efi_loader/efi_setup.c | 46 | ||||
-rw-r--r-- | lib/efi_loader/efi_var_common.c | 13 |
7 files changed, 124 insertions, 43 deletions
diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index b9351d4..a3d944d 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -187,5 +187,4 @@ CONFIG_OF_LIBFDT_OVERLAY=y CONFIG_EFI_SET_TIME=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y -CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y diff --git a/include/efi_loader.h b/include/efi_loader.h index 0a9c82a..b81180c 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -972,4 +972,5 @@ efi_status_t efi_esrt_register(void); * - error code otherwise. */ efi_status_t efi_esrt_populate(void); +efi_status_t efi_load_capsule_drivers(void); #endif /* _EFI_LOADER_H */ diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 6242cac..156b391 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -137,6 +137,16 @@ config EFI_CAPSULE_ON_DISK under a specific directory on UEFI system partition instead of via UpdateCapsule API. +config EFI_IGNORE_OSINDICATIONS + bool "Ignore OsIndications for CapsuleUpdate on-disk" + depends on EFI_CAPSULE_ON_DISK + default n + help + There are boards where U-Boot does not support SetVariable at runtime. + Select this option if you want to use the capsule-on-disk feature + without setting the EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED + flag in variable OsIndications. + config EFI_CAPSULE_ON_DISK_EARLY bool "Initiate capsule-on-disk at U-Boot boottime" depends on EFI_CAPSULE_ON_DISK @@ -161,6 +171,28 @@ config EFI_CAPSULE_FIRMWARE_MANAGEMENT Select this option if you want to enable capsule-based firmware update using Firmware Management Protocol. +config EFI_CAPSULE_FIRMWARE_FIT + bool "FMP driver for FIT images" + depends on FIT + depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT + select UPDATE_FIT + select DFU + select EFI_CAPSULE_FIRMWARE + help + Select this option if you want to enable firmware management protocol + driver for FIT image + +config EFI_CAPSULE_FIRMWARE_RAW + bool "FMP driver for raw images" + depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT + depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_FIT) + select DFU_WRITE_ALT + select DFU + select EFI_CAPSULE_FIRMWARE + help + Select this option if you want to enable firmware management protocol + driver for raw image + config EFI_CAPSULE_AUTHENTICATE bool "Update Capsule authentication" depends on EFI_CAPSULE_FIRMWARE @@ -181,29 +213,6 @@ config EFI_CAPSULE_AUTHENTICATE Select this option if you want to enable capsule authentication -config EFI_CAPSULE_FIRMWARE_FIT - bool "FMP driver for FIT image" - depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT - depends on FIT - select UPDATE_FIT - select DFU - select EFI_CAPSULE_FIRMWARE - default n - help - Select this option if you want to enable firmware management protocol - driver for FIT image - -config EFI_CAPSULE_FIRMWARE_RAW - bool "FMP driver for raw image" - depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT - select DFU - select DFU_WRITE_ALT - select EFI_CAPSULE_FIRMWARE - default n - help - Select this option if you want to enable firmware management protocol - driver for raw image - config EFI_DEVICE_PATH_TO_TEXT bool "Device path to text protocol" default y diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index 60309d4..50bed32 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -919,13 +919,13 @@ static void efi_capsule_scan_done(void) } /** - * arch_efi_load_capsule_drivers - initialize capsule drivers + * efi_load_capsule_drivers - initialize capsule drivers * - * Architecture or board specific initialization routine + * Generic FMP drivers backed by DFU * * Return: status code */ -efi_status_t __weak arch_efi_load_capsule_drivers(void) +efi_status_t __weak efi_load_capsule_drivers(void) { __maybe_unused efi_handle_t handle; efi_status_t ret = EFI_SUCCESS; @@ -940,7 +940,7 @@ efi_status_t __weak arch_efi_load_capsule_drivers(void) if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_RAW)) { handle = NULL; ret = EFI_CALL(efi_install_multiple_protocol_interfaces( - &efi_root, + &handle, &efi_guid_firmware_management_protocol, &efi_fmp_raw, NULL)); } @@ -949,6 +949,33 @@ efi_status_t __weak arch_efi_load_capsule_drivers(void) } /** + * check_run_capsules - Check whether capsule update should run + * + * The spec says OsIndications must be set in order to run the capsule update + * on-disk. Since U-Boot doesn't support runtime SetVariable, allow capsules to + * run explicitly if CONFIG_EFI_IGNORE_OSINDICATIONS is selected + */ +static bool check_run_capsules(void) +{ + u64 os_indications; + efi_uintn_t size; + efi_status_t ret; + + if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS)) + return true; + + size = sizeof(os_indications); + ret = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid, + NULL, &size, &os_indications, NULL); + if (ret == EFI_SUCCESS && + (os_indications + & EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED)) + return true; + + return false; +} + +/** * efi_launch_capsule - launch capsules * * Launch all the capsules in system at boot time. @@ -958,29 +985,17 @@ efi_status_t __weak arch_efi_load_capsule_drivers(void) */ efi_status_t efi_launch_capsules(void) { - u64 os_indications; - efi_uintn_t size; struct efi_capsule_header *capsule = NULL; u16 **files; unsigned int nfiles, index, i; u16 variable_name16[12]; efi_status_t ret; - size = sizeof(os_indications); - ret = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid, - NULL, &size, &os_indications, NULL); - if (ret != EFI_SUCCESS || - !(os_indications - & EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED)) + if (!check_run_capsules()) return EFI_SUCCESS; index = get_last_capsule(); - /* Load capsule drivers */ - ret = arch_efi_load_capsule_drivers(); - if (ret != EFI_SUCCESS) - return ret; - /* * Find capsules on disk. * All the capsules are collected at the beginning because diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c index 6040f3a..3b012e1 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -342,7 +342,7 @@ static void query_console_size(void) int rows = 25, cols = 80; int ret = -ENODEV; - if IS_ENABLED(CONFIG_DM_VIDEO) + if (IS_ENABLED(CONFIG_DM_VIDEO)) ret = query_vidconsole(&rows, &cols); if (ret) ret = query_console_serial(&rows, &cols); diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index 3c5cf9a..a2338d7 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -5,9 +5,12 @@ * Copyright (c) 2016-2018 Alexander Graf et al. */ +#define LOG_CATEGORY LOGC_EFI + #include <common.h> #include <efi_loader.h> #include <efi_variable.h> +#include <log.h> #define OBJ_LIST_NOT_INITIALIZED 1 @@ -171,6 +174,37 @@ static efi_status_t efi_init_os_indications(void) &os_indications_supported, false); } + +/** + * efi_clear_os_indications() - clear OsIndications + * + * Clear EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED + */ +static efi_status_t efi_clear_os_indications(void) +{ + efi_uintn_t size; + u64 os_indications; + efi_status_t ret; + + size = sizeof(os_indications); + ret = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid, + NULL, &size, &os_indications, NULL); + if (ret != EFI_SUCCESS) + os_indications = 0; + else + os_indications &= + ~EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED; + ret = efi_set_variable_int(L"OsIndications", &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(os_indications), &os_indications, + false); + if (ret != EFI_SUCCESS) + log_err("Setting %ls failed\n", L"OsIndications"); + return ret; +} + /** * efi_init_obj_list() - Initialize and populate EFI object list * @@ -178,7 +212,7 @@ static efi_status_t efi_init_os_indications(void) */ efi_status_t efi_init_obj_list(void) { - efi_status_t ret = EFI_SUCCESS; + efi_status_t r, ret = EFI_SUCCESS; /* Initialize once only */ if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED) @@ -254,6 +288,12 @@ efi_status_t efi_init_obj_list(void) if (ret != EFI_SUCCESS) goto out; + if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)) { + ret = efi_load_capsule_drivers(); + if (ret != EFI_SUCCESS) + goto out; + } + #if defined(CONFIG_LCD) || defined(CONFIG_DM_VIDEO) ret = efi_gop_register(); if (ret != EFI_SUCCESS) @@ -291,7 +331,11 @@ efi_status_t efi_init_obj_list(void) if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK) && !IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY)) ret = efi_launch_capsules(); + out: + r = efi_clear_os_indications(); + if (ret == EFI_SUCCESS) + ret = r; efi_obj_list_initialized = ret; return ret; } diff --git a/lib/efi_loader/efi_var_common.c b/lib/efi_loader/efi_var_common.c index 83479dd..3d92afe 100644 --- a/lib/efi_loader/efi_var_common.c +++ b/lib/efi_loader/efi_var_common.c @@ -163,6 +163,19 @@ efi_status_t EFIAPI efi_query_variable_info( EFI_ENTRY("%x %p %p %p", attributes, maximum_variable_storage_size, remaining_variable_storage_size, maximum_variable_size); + if (!maximum_variable_storage_size || + !remaining_variable_storage_size || + !maximum_variable_size || + !(attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS)) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + if ((attributes & ~(u32)EFI_VARIABLE_MASK) || + (attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) || + (attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) || + (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT) && + (attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS))) + return EFI_EXIT(EFI_UNSUPPORTED); + ret = efi_query_variable_info_int(attributes, maximum_variable_storage_size, remaining_variable_storage_size, |