aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorIlias Apalodimas2021-06-29 07:55:51 +0300
committerHeinrich Schuchardt2021-07-02 18:29:06 +0200
commit0fa5020c024e49222ca97ead3502b332d35dea76 (patch)
tree10b8e9309e37a4f9b0fd2dfc2a6c75812e44d7ac /lib
parent149108a3eb594b03561073aa6fd512cacab57c62 (diff)
efi_loader: Allow capsule update on-disk without checking OsIndications
Although U-Boot supports capsule update on-disk, it's lack of support for SetVariable at runtime prevents applications like fwupd from using it. In order to perform the capsule update on-disk the spec says that the OS must copy the capsule to the \EFI\UpdateCapsule directory and set a bit in the OsIndications variable. The firmware then checks for the EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED bit in OsIndications variable, which is set by the submitter to trigger processing of the capsule on the next reboot. Let's add a config option which ignores the bit and just relies on the capsule being present. Since U-Boot deletes the capsule while processing it, we won't end up applying it multiple times. Note that this is allowed for all capsules. In the future, once authenticated capsules are fully supported, we can limit the functionality to those only. Signed-off-by: apalos <ilias.apalodimas@linaro.org> Reword Kconfig description. Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Diffstat (limited to 'lib')
-rw-r--r--lib/efi_loader/Kconfig10
-rw-r--r--lib/efi_loader/efi_capsule.c36
2 files changed, 38 insertions, 8 deletions
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 684adfb6237..156b3915211 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
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index d7136035d8f..50bed32bfb3 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -949,6 +949,33 @@ efi_status_t __weak 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,20 +985,13 @@ efi_status_t __weak 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();