Linux EFI development
 help / color / mirror / Atom feed
* [PATCH] efi: vars: commonize the 512-byte name buffer quirk
@ 2026-08-15  7:48 Jonggeun Park
  0 siblings, 0 replies; only message in thread
From: Jonggeun Park @ 2026-08-15  7:48 UTC (permalink / raw)
  To: ardb, jk
  Cc: kees, tony.luck, gpiccoli, ilias.apalodimas, linux-efi,
	linux-kernel, Jonggeun Park

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


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-08-15  7:48 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-15  7:48 [PATCH] efi: vars: commonize the 512-byte name buffer quirk Jonggeun Park

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox