From: Jonggeun Park <jakejgpark@gmail.com>
To: ardb@kernel.org, jk@ozlabs.org
Cc: kees@kernel.org, tony.luck@intel.com, gpiccoli@igalia.com,
ilias.apalodimas@linaro.org, linux-efi@vger.kernel.org,
linux-kernel@vger.kernel.org,
Jonggeun Park <jakejgpark@gmail.com>
Subject: [PATCH] efi: vars: commonize the 512-byte name buffer quirk
Date: Sat, 15 Aug 2026 16:48:44 +0900 [thread overview]
Message-ID: <20260815074844.1330-1-jakejgpark@gmail.com> (raw)
Some old UEFI implementations reject GetNextVariableName() calls with
a name buffer size larger than 512 bytes. Both efivar_init() and
efi_pstore_read() open-code the same workaround of resetting the size
to 512 on every iteration.
Introduce efivar_get_next_variable_safe() which keeps this quirk in a
single place, resolving the TODO in efi-pstore.c.
No functional change intended.
Signed-off-by: Jonggeun Park <jakejgpark@gmail.com>
---
drivers/firmware/efi/efi-pstore.c | 16 +++++-----------
drivers/firmware/efi/vars.c | 21 +++++++++++++++++++++
fs/efivarfs/vars.c | 4 +---
include/linux/efi.h | 4 ++++
4 files changed, 31 insertions(+), 14 deletions(-)
diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
index a5db3534f..a135d6e2f 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -164,16 +164,6 @@ static ssize_t efi_pstore_read(struct pstore_record *record)
efi_status_t status;
for (;;) {
- /*
- * A small set of old UEFI implementations reject sizes
- * above a certain threshold, the lowest seen in the wild
- * is 512.
- *
- * TODO: Commonize with the iteration implementation in
- * fs/efivarfs to keep all the quirks in one place.
- */
- varname_size = 512;
-
/*
* If this is the first read() call in the pstore enumeration,
* varname will be the empty string, and the GetNextVariable()
@@ -185,8 +175,12 @@ static ssize_t efi_pstore_read(struct pstore_record *record)
* store varname in record->psi->data. Given that we only
* enumerate variables with the efi-pstore GUID, there is no
* need to record the guid return value.
+ *
+ * The 512-byte name buffer quirk is handled inside
+ * efivar_get_next_variable_safe().
*/
- status = efivar_get_next_variable(&varname_size, varname, &guid);
+ status = efivar_get_next_variable_safe(&varname_size, varname,
+ &guid);
if (status == EFI_NOT_FOUND)
return 0;
diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
index 3700e9869..8e69f3632 100644
--- a/drivers/firmware/efi/vars.c
+++ b/drivers/firmware/efi/vars.c
@@ -265,3 +265,24 @@ efi_status_t efivar_query_variable_info(u32 attr,
remaining_space, max_variable_size);
}
EXPORT_SYMBOL_NS_GPL(efivar_query_variable_info, "EFIVAR");
+
+/*
+ * efivar_get_next_variable_safe() - enumerate the next name/vendor pair
+ *
+ * Wrapper around efivar_get_next_variable() that keeps the 512-byte name
+ * buffer quirk in one place. Some old UEFI implementations reject name buffer
+ * sizes larger than 512 bytes (the lowest seen in the wild), so this always
+ * requests 512 bytes; callers must provide a buffer of at least that size.
+ *
+ * Must be called with efivars_lock held.
+ */
+efi_status_t efivar_get_next_variable_safe(unsigned long *name_size,
+ efi_char16_t *name,
+ efi_guid_t *vendor)
+{
+ BUILD_BUG_ON(EFI_VAR_NAME_LEN < 512);
+ *name_size = 512;
+
+ return efivar_get_next_variable(name_size, name, vendor);
+}
+EXPORT_SYMBOL_NS_GPL(efivar_get_next_variable_safe, "EFIVAR");
diff --git a/fs/efivarfs/vars.c b/fs/efivarfs/vars.c
index 6833c3d24..ee55a26cb 100644
--- a/fs/efivarfs/vars.c
+++ b/fs/efivarfs/vars.c
@@ -398,10 +398,8 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
*/
do {
- variable_name_size = 512;
- BUILD_BUG_ON(EFI_VAR_NAME_LEN < 512);
- status = efivar_get_next_variable(&variable_name_size,
+ status = efivar_get_next_variable_safe(&variable_name_size,
variable_name,
&vendor_guid);
switch (status) {
diff --git a/include/linux/efi.h b/include/linux/efi.h
index ccbc35479..f36505aa0 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1076,6 +1076,10 @@ efi_status_t efivar_get_variable(efi_char16_t *name, efi_guid_t *vendor,
efi_status_t efivar_get_next_variable(unsigned long *name_size,
efi_char16_t *name, efi_guid_t *vendor);
+efi_status_t efivar_get_next_variable_safe(unsigned long *name_size,
+ efi_char16_t *name,
+ efi_guid_t *vendor);
+
efi_status_t efivar_set_variable_locked(efi_char16_t *name, efi_guid_t *vendor,
u32 attr, unsigned long data_size,
void *data, bool nonblocking);
--
2.43.0
next reply other threads:[~2026-08-15 7:48 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-15 7:48 Jonggeun Park [this message]
2026-09-03 9:55 ` [PATCH] efi: vars: commonize the 512-byte name buffer quirk Ard Biesheuvel
2026-09-03 11:55 ` [PATCH v2] " Jonggeun Park
2026-09-03 20:03 ` Ard Biesheuvel
2026-09-03 21:28 ` David Laight
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260815074844.1330-1-jakejgpark@gmail.com \
--to=jakejgpark@gmail.com \
--cc=ardb@kernel.org \
--cc=gpiccoli@igalia.com \
--cc=ilias.apalodimas@linaro.org \
--cc=jk@ozlabs.org \
--cc=kees@kernel.org \
--cc=linux-efi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tony.luck@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.