aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2021-07-02 15:04:07 -0400
committerTom Rini <trini@konsulko.com>2021-07-02 15:04:07 -0400
commit62c7e40a04c8c78615060073942e2e48f722c22b (patch)
tree3ee01b254834bcb7c102197f4b49e083ecc7b471
parent760d2f9e9e66c7eacfbcff21dcd3733d16526438 (diff)
parent0fa5020c024e49222ca97ead3502b332d35dea76 (diff)
downloadu-boot-WIP/02Jul2021.zip
u-boot-WIP/02Jul2021.tar.gz
u-boot-WIP/02Jul2021.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_defconfig1
-rw-r--r--include/efi_loader.h1
-rw-r--r--lib/efi_loader/Kconfig55
-rw-r--r--lib/efi_loader/efi_capsule.c49
-rw-r--r--lib/efi_loader/efi_console.c2
-rw-r--r--lib/efi_loader/efi_setup.c46
-rw-r--r--lib/efi_loader/efi_var_common.c13
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,