Hi Val,

On Wed, 3 Dec 2025 at 06:29, Val Packett <[email protected]> wrote:
>
> On some platforms, EFI variable services only become available when an
> appropriate TEE driver is initialized such as qseecom, gsmi or stmm.
>
> This would work fine when efi_pstore was built as a module and loaded
> late by userspace, but with CONFIG_EFI_VARS_PSTORE=y this driver would
> quit due to non-writable efivars before the necessary driver had any
> chance to load.

The problem, at least for OP-TEE/StMM, is that writing the variables
to an RPMB depends on a userspace application If CONFIG_RPMB is not
selected. We have no guarantees that the app will still be alive.
I don't know how gsmi or qseecom deal with writing variables. We can
probably allow it for StMM if CONFIG_RPMB is enabled, but we'll have
the right trigger to do so.

>
> Listen to efivar_ops_nh notifications and retry the initialization when
> writable EFI variable ops become available.
>
> Signed-off-by: Val Packett <[email protected]>

Thanks
/Ilias
> ---
>  drivers/firmware/efi/efi-pstore.c | 32 +++++++++++++++++++++++++++----
>  1 file changed, 28 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/firmware/efi/efi-pstore.c 
> b/drivers/firmware/efi/efi-pstore.c
> index a253b6144945..ad5192d5892e 100644
> --- a/drivers/firmware/efi/efi-pstore.c
> +++ b/drivers/firmware/efi/efi-pstore.c
> @@ -253,14 +253,11 @@ static struct pstore_info efi_pstore_info = {
>         .erase          = efi_pstore_erase,
>  };
>
> -static int efivars_pstore_init(void)
> +static int efivars_pstore_setup(void)
>  {
>         if (!efivar_supports_writes())
>                 return 0;
>
> -       if (pstore_disable)
> -               return 0;
> -
>         /*
>          * Notice that 1024 is the minimum here to prevent issues with
>          * decompression algorithms that were spotted during tests;
> @@ -285,8 +282,35 @@ static int efivars_pstore_init(void)
>         return 0;
>  }
>
> +static int efivars_pstore_ops_notifier(struct notifier_block *nb,
> +                                unsigned long event, void *data)
> +{
> +       if (event == EFIVAR_OPS_RDWR && !efi_pstore_info.bufsize)
> +               efivars_pstore_setup();
> +
> +       return NOTIFY_OK;
> +}
> +
> +static struct notifier_block efivars_pstore_ops_notifier_block = {
> +       .notifier_call = efivars_pstore_ops_notifier,
> +};
> +
> +static int efivars_pstore_init(void)
> +{
> +       if (pstore_disable)
> +               return 0;
> +
> +       blocking_notifier_chain_register(&efivar_ops_nh,
> +                                       &efivars_pstore_ops_notifier_block);
> +
> +       return efivars_pstore_setup();
> +}
> +
>  static void efivars_pstore_exit(void)
>  {
> +       blocking_notifier_chain_unregister(&efivar_ops_nh,
> +                                       &efivars_pstore_ops_notifier_block);
> +
>         if (!efi_pstore_info.bufsize)
>                 return;
>
> --
> 2.51.0
>
>

Reply via email to