[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251203042850.14210-1-val@packett.cool>
Date: Wed, 3 Dec 2025 01:28:29 -0300
From: Val Packett <val@...kett.cool>
To: Kees Cook <kees@...nel.org>,
Tony Luck <tony.luck@...el.com>,
"Guilherme G. Piccoli" <gpiccoli@...lia.com>,
Ard Biesheuvel <ardb@...nel.org>
Cc: Val Packett <val@...kett.cool>,
linux-hardening@...r.kernel.org,
linux-efi@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH] efi: pstore: Support late setup with TEE-backed efivars ops
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.
Listen to efivar_ops_nh notifications and retry the initialization when
writable EFI variable ops become available.
Signed-off-by: Val Packett <val@...kett.cool>
---
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
Powered by blists - more mailing lists