[PATCH] efi_loader: Allow capsule update on-disk without checking OsIndications

Heinrich Schuchardt xypron.glpk at gmx.de
Tue Jun 29 09:43:40 CEST 2021


On 6/29/21 6:55 AM, Ilias Apalodimas wrote:
> From: apalos <ilias.apalodimas at linaro.org>
>
> 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 submitter to trigger processing of the capsule
> on next reboot.
>
> Let's add a config option which ignores the bit checking in OsIndications
> and just rely on the capsule being present.  Since U-Boot deletes the
> capsule while processing it, we won't end up running it multiple times.
>
> Note that this is allowed for all capsules.  In the future once,
> authenticated capsules is fully supported, we can limit the functionality
> to those only.
>
> Signed-off-by: apalos <ilias.apalodimas at linaro.org>
> ---
>   lib/efi_loader/Kconfig       |  9 +++++++++
>   lib/efi_loader/efi_capsule.c | 36 ++++++++++++++++++++++++++++--------
>   2 files changed, 37 insertions(+), 8 deletions(-)
>
> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> index 684adfb62379..5a3820e76122 100644
> --- a/lib/efi_loader/Kconfig
> +++ b/lib/efi_loader/Kconfig
> @@ -137,6 +137,15 @@ 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 were we can't support SetVariable at runtime.
> +	  Select this option if you want to use capsule-on-disk feature,
> +	  without setting the OsIndications bit.
> +
>   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 d7136035d8f9..50bed32bfb3b 100644
> --- a/lib/efi_loader/efi_capsule.c
> +++ b/lib/efi_loader/efi_capsule.c
> @@ -948,6 +948,33 @@ efi_status_t __weak efi_load_capsule_drivers(void)
>   	return ret;
>   }
>
> +/**
> + * 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))

The bit EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED must be
cleared in OsIndications after successfully applying the capsule. See
related patch

[PATCH 1/1] efi_loader: fix set_capsule_result()
https://lists.denx.de/pipermail/u-boot/2021-June/453111.html

Reviewed-by: Heinrich Schuchardt <xypron.glpk at gmx.de>

> +		return true;
> +
> +	return false;
> +}
> +
>   /**
>    * efi_launch_capsule - launch capsules
>    *
> @@ -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();
>



More information about the U-Boot mailing list