* [PATCH v2 00/10] efi/libstub: Avoid UTF-16 conversion busywork
@ 2026-09-09 11:55 Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 01/10] x86/boot: Drop pointless re-implementation of panic() Ard Biesheuvel
` (9 more replies)
0 siblings, 10 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2026-09-09 11:55 UTC (permalink / raw)
To: linux-efi; +Cc: linux-kernel, Ard Biesheuvel, Vincent Mailhol, x86
From: Ard Biesheuvel <ardb@kernel.org>
The EFI libstub performs some redundant conversions between UTF-16 and
UTF-8 and back again, which includes dealing with surrogate pairs, which
UEFI implementations themselves simply ignore.
So drop all the homegrown code, and use the existing UCS-2 (== UTF-16
without surrogate pairs) library code where conversion to UTF-8 is
actually needed (the kernel command line).
The remaining handling involves the EFI console, which supports wide
characters natively, so just use those directly.
Changes since v1 [0]:
- drop size limit from ucs2_strscpy() instead of just the WARN()
- suppress modinfo sections from ucs2_string when __DISABLE_EXPORTS is
defined
- allow the input limit and max output size to be passed separately to
ucs2_to_utf8()
- reimplement efi_convert_cmdline() to optimize the common case, and
only process the input character by character if its size exceeds
COMMAND_LINE_SIZE
- use memcpy() to avoid strscpy() semantics in handling of %ls
- incorporate Vincent's patch (which inspired this work) for
completeness
Cc: Vincent Mailhol <mailhol@kernel.org>
Cc: x86@kernel.org
[0] https://lore.kernel.org/all/20260906130817.1151961-9-ardb@kernel.org
Ard Biesheuvel (9):
x86/boot: Drop pointless re-implementation of panic()
lib/ucs2_string: Drop arbitrary input size limit and associated WARN()
lib/ucs2_string: Suppress modinfo when __DISABLE_EXPORTS is set
lib/ucs2_string: Split out ucs2_as_utf8_l() taking a separate limit
efi/libstub: Use ucs2_string library for UTF-16 to UTF-8 conversion
efi/libstub: Avoid efi_puts() for compile time constant strings
efi/libstub: Output UTF-16 directly from vsnprintf()
efi/libstub: Add support for printing human readable GUIDs
efi/libstub: Add efi_snprintf() to construct wide strings
Vincent Mailhol (1):
efi/libstub: add initial Boot Loader Interface support
arch/x86/boot/compressed/error.c | 19 ---
arch/x86/boot/compressed/error.h | 1 -
arch/x86/boot/compressed/mem.c | 2 +-
drivers/firmware/efi/libstub/Makefile | 3 +-
drivers/firmware/efi/libstub/bli.c | 87 ++++++++++++
drivers/firmware/efi/libstub/efi-stub-helper.c | 100 +++++--------
drivers/firmware/efi/libstub/efi-stub.c | 1 +
drivers/firmware/efi/libstub/efistub.h | 8 +-
drivers/firmware/efi/libstub/gop.c | 6 +-
drivers/firmware/efi/libstub/printk.c | 95 ++-----------
drivers/firmware/efi/libstub/vsprintf.c | 150 +++++++-------------
drivers/firmware/efi/libstub/x86-stub.c | 1 +
include/linux/efi.h | 22 +++
include/linux/ucs2_string.h | 11 +-
lib/ucs2_string.c | 10 +-
15 files changed, 241 insertions(+), 275 deletions(-)
create mode 100644 drivers/firmware/efi/libstub/bli.c
--
2.55.0.1003.g10538fe699-goog
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 01/10] x86/boot: Drop pointless re-implementation of panic()
2026-09-09 11:55 [PATCH v2 00/10] efi/libstub: Avoid UTF-16 conversion busywork Ard Biesheuvel
@ 2026-09-09 11:55 ` Ard Biesheuvel
2026-09-09 19:14 ` Borislav Petkov
2026-09-09 11:55 ` [PATCH v2 02/10] lib/ucs2_string: Drop arbitrary input size limit and associated WARN() Ard Biesheuvel
` (8 subsequent siblings)
9 siblings, 1 reply; 15+ messages in thread
From: Ard Biesheuvel @ 2026-09-09 11:55 UTC (permalink / raw)
To: linux-efi; +Cc: linux-kernel, Ard Biesheuvel, Vincent Mailhol, x86
From: Ard Biesheuvel <ardb@kernel.org>
The decompressor has its own implementation of panic(), which is based
on the vsnprintf() routine provided by the EFI stub.
Relying on the EFI stub from code that does not execute in the context
of the EFI boot services is a bad idea. It is also completely pointless
in this case, given that the only user of this version of panic() only
passes a compile time constant string, without any printf conversions.
So use error() instead of panic() in that case, and drop the panic()
implementation entirely. This is needed so that the EFI stub's
vsnprintf() can be modified in a manner that is incompatible with the
expectations of this caller.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/x86/boot/compressed/error.c | 19 -------------------
arch/x86/boot/compressed/error.h | 1 -
arch/x86/boot/compressed/mem.c | 2 +-
3 files changed, 1 insertion(+), 21 deletions(-)
diff --git a/arch/x86/boot/compressed/error.c b/arch/x86/boot/compressed/error.c
index 19a8251de506..ce5ed7d8265e 100644
--- a/arch/x86/boot/compressed/error.c
+++ b/arch/x86/boot/compressed/error.c
@@ -22,22 +22,3 @@ void error(char *m)
while (1)
asm("hlt");
}
-
-/* EFI libstub provides vsnprintf() */
-#ifdef CONFIG_EFI_STUB
-void panic(const char *fmt, ...)
-{
- static char buf[1024];
- va_list args;
- int len;
-
- va_start(args, fmt);
- len = vsnprintf(buf, sizeof(buf), fmt, args);
- va_end(args);
-
- if (len && buf[len - 1] == '\n')
- buf[len - 1] = '\0';
-
- error(buf);
-}
-#endif
diff --git a/arch/x86/boot/compressed/error.h b/arch/x86/boot/compressed/error.h
index 31f9e080d61a..87062dea9a20 100644
--- a/arch/x86/boot/compressed/error.h
+++ b/arch/x86/boot/compressed/error.h
@@ -6,6 +6,5 @@
void warn(const char *m);
void error(char *m) __noreturn;
-void panic(const char *fmt, ...) __noreturn __cold;
#endif /* BOOT_COMPRESSED_ERROR_H */
diff --git a/arch/x86/boot/compressed/mem.c b/arch/x86/boot/compressed/mem.c
index 0e9f84ab4bdc..e1c017b55184 100644
--- a/arch/x86/boot/compressed/mem.c
+++ b/arch/x86/boot/compressed/mem.c
@@ -37,7 +37,7 @@ void arch_accept_memory(phys_addr_t start, phys_addr_t end)
/* Platform-specific memory-acceptance call goes here */
if (early_is_tdx_guest()) {
if (!tdx_accept_memory(start, end))
- panic("TDX: Failed to accept memory\n");
+ error("TDX: Failed to accept memory\n");
} else if (early_is_sevsnp_guest()) {
snp_accept_memory(start, end);
} else {
--
2.55.0.1003.g10538fe699-goog
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 02/10] lib/ucs2_string: Drop arbitrary input size limit and associated WARN()
2026-09-09 11:55 [PATCH v2 00/10] efi/libstub: Avoid UTF-16 conversion busywork Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 01/10] x86/boot: Drop pointless re-implementation of panic() Ard Biesheuvel
@ 2026-09-09 11:55 ` Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 03/10] lib/ucs2_string: Suppress modinfo when __DISABLE_EXPORTS is set Ard Biesheuvel
` (7 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2026-09-09 11:55 UTC (permalink / raw)
To: linux-efi; +Cc: linux-kernel, Ard Biesheuvel, Vincent Mailhol, x86
From: Ard Biesheuvel <ardb@kernel.org>
It's not really the job of library code to WARN and potentially bring
down the system (with panic_on_warn=1) on a condition that is fairly
arbitrary to begin with.
So drop the WARN_ON_ONCE() as well as the condition from ucs2_strscpy().
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
lib/ucs2_string.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/ucs2_string.c b/lib/ucs2_string.c
index 1f7dd4eb640a..d66fef9c9b81 100644
--- a/lib/ucs2_string.c
+++ b/lib/ucs2_string.c
@@ -57,7 +57,7 @@ ssize_t ucs2_strscpy(ucs2_char_t *dst, const ucs2_char_t *src, size_t count)
* Ensure that we have a valid amount of space. We need to store at
* least one NUL-character.
*/
- if (count == 0 || WARN_ON_ONCE(count > INT_MAX / sizeof(*dst)))
+ if (count == 0)
return -E2BIG;
/*
--
2.55.0.1003.g10538fe699-goog
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 03/10] lib/ucs2_string: Suppress modinfo when __DISABLE_EXPORTS is set
2026-09-09 11:55 [PATCH v2 00/10] efi/libstub: Avoid UTF-16 conversion busywork Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 01/10] x86/boot: Drop pointless re-implementation of panic() Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 02/10] lib/ucs2_string: Drop arbitrary input size limit and associated WARN() Ard Biesheuvel
@ 2026-09-09 11:55 ` Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 04/10] lib/ucs2_string: Split out ucs2_as_utf8_l() taking a separate limit Ard Biesheuvel
` (6 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2026-09-09 11:55 UTC (permalink / raw)
To: linux-efi; +Cc: linux-kernel, Ard Biesheuvel, Vincent Mailhol, x86
From: Ard Biesheuvel <ardb@kernel.org>
Allow the UCS-2 string library to be reused in the EFI stub, by
suppressing the modinfo data that is usually emitted so that the library
can be built as a module.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
lib/ucs2_string.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/ucs2_string.c b/lib/ucs2_string.c
index d66fef9c9b81..f75fb4f7961a 100644
--- a/lib/ucs2_string.c
+++ b/lib/ucs2_string.c
@@ -165,5 +165,7 @@ ucs2_as_utf8(u8 *dest, const ucs2_char_t *src, unsigned long maxlength)
}
EXPORT_SYMBOL(ucs2_as_utf8);
+#ifndef __DISABLE_EXPORTS
MODULE_DESCRIPTION("UCS2 string handling");
MODULE_LICENSE("GPL v2");
+#endif
--
2.55.0.1003.g10538fe699-goog
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 04/10] lib/ucs2_string: Split out ucs2_as_utf8_l() taking a separate limit
2026-09-09 11:55 [PATCH v2 00/10] efi/libstub: Avoid UTF-16 conversion busywork Ard Biesheuvel
` (2 preceding siblings ...)
2026-09-09 11:55 ` [PATCH v2 03/10] lib/ucs2_string: Suppress modinfo when __DISABLE_EXPORTS is set Ard Biesheuvel
@ 2026-09-09 11:55 ` Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 05/10] efi/libstub: Use ucs2_string library for UTF-16 to UTF-8 conversion Ard Biesheuvel
` (5 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2026-09-09 11:55 UTC (permalink / raw)
To: linux-efi; +Cc: linux-kernel, Ard Biesheuvel, Vincent Mailhol, x86
From: Ard Biesheuvel <ardb@kernel.org>
ucs2_as_utf() takes a maxlength argument, which specifies how many bytes
the function is permitted to store into the destination buffer.
The same value is used as an upper bound for the ucs2_strnlen()
invocation, which is reasonable in the general case, as each UCS-2
character produces at least one byte of UTF-8 output, and so there is
never a need to process more than 'maxlength' UCS-2 characters.
However, if the UCS-2 string is not NUL terminated, ucs2_strnlen() may
read past the end of the buffer if 'maxlength' is set to a high value.
Current callers pass UCS-2 strings that are expected to be NUL
terminated, but for processing the load options in the EFI stub, a
version is needed that takes a separate limit argument. So split that
off from the current implementation.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
include/linux/ucs2_string.h | 11 ++++++++++-
lib/ucs2_string.c | 6 +++---
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/include/linux/ucs2_string.h b/include/linux/ucs2_string.h
index c499ae809c7d..74f23ca5a967 100644
--- a/include/linux/ucs2_string.h
+++ b/include/linux/ucs2_string.h
@@ -14,7 +14,16 @@ ssize_t ucs2_strscpy(ucs2_char_t *dst, const ucs2_char_t *src, size_t count);
int ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len);
unsigned long ucs2_utf8size(const ucs2_char_t *src);
+unsigned long
+ucs2_as_utf8_l(u8 *dest, const ucs2_char_t *src, unsigned long limit,
+ unsigned long maxlength);
+
+static inline
unsigned long ucs2_as_utf8(u8 *dest, const ucs2_char_t *src,
- unsigned long maxlength);
+ unsigned long maxlength)
+{
+ return ucs2_as_utf8_l(dest, src, ucs2_strnlen(src, maxlength),
+ maxlength);
+}
#endif /* _LINUX_UCS2_STRING_H_ */
diff --git a/lib/ucs2_string.c b/lib/ucs2_string.c
index f75fb4f7961a..2df9bef79eea 100644
--- a/lib/ucs2_string.c
+++ b/lib/ucs2_string.c
@@ -132,11 +132,11 @@ EXPORT_SYMBOL(ucs2_utf8size);
* final NUL character.
*/
unsigned long
-ucs2_as_utf8(u8 *dest, const ucs2_char_t *src, unsigned long maxlength)
+ucs2_as_utf8_l(u8 *dest, const ucs2_char_t *src, unsigned long limit,
+ unsigned long maxlength)
{
unsigned int i;
unsigned long j = 0;
- unsigned long limit = ucs2_strnlen(src, maxlength);
for (i = 0; maxlength && i < limit; i++) {
u16 c = src[i];
@@ -163,7 +163,7 @@ ucs2_as_utf8(u8 *dest, const ucs2_char_t *src, unsigned long maxlength)
dest[j] = '\0';
return j;
}
-EXPORT_SYMBOL(ucs2_as_utf8);
+EXPORT_SYMBOL(ucs2_as_utf8_l);
#ifndef __DISABLE_EXPORTS
MODULE_DESCRIPTION("UCS2 string handling");
--
2.55.0.1003.g10538fe699-goog
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 05/10] efi/libstub: Use ucs2_string library for UTF-16 to UTF-8 conversion
2026-09-09 11:55 [PATCH v2 00/10] efi/libstub: Avoid UTF-16 conversion busywork Ard Biesheuvel
` (3 preceding siblings ...)
2026-09-09 11:55 ` [PATCH v2 04/10] lib/ucs2_string: Split out ucs2_as_utf8_l() taking a separate limit Ard Biesheuvel
@ 2026-09-09 11:55 ` Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 06/10] efi/libstub: Avoid efi_puts() for compile time constant strings Ard Biesheuvel
` (4 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2026-09-09 11:55 UTC (permalink / raw)
To: linux-efi; +Cc: linux-kernel, Ard Biesheuvel, Vincent Mailhol, x86
From: Ard Biesheuvel <ardb@kernel.org>
Don't rely on sprintf() with a wide string conversion modifier to
convert the command line from UTF-16 to UTF-8. Instead, use the
existing ucs2 string library routine that does the same. Note that while
UEFI claims support for UTF-16, in practice it ignores surrogate pairs
entirely, and so the simplified UCS-2 character set (where each
character takes up exactly 2 bytes) is sufficient here.
This removes the only user of sprintf() in the EFI stub, so drop that
function as well.
Since boot memory is plentiful on UEFI systems, just establish a worst
case upper bound for the size of the buffer (which can never exceed
COMMAND_LINE_SIZE), and allocate that first. Then, perform the
conversion, and only fall back to processing the command line character
by character if that resulted in truncation. This makes the common
execution path much simpler.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
drivers/firmware/efi/libstub/Makefile | 3 +-
drivers/firmware/efi/libstub/efi-stub-helper.c | 100 ++++++++------------
drivers/firmware/efi/libstub/vsprintf.c | 11 ---
3 files changed, 41 insertions(+), 73 deletions(-)
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index 77a2b2d74f3f..12c0c7deb5cb 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -66,7 +66,8 @@ KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o \
file.o mem.o random.o randomalloc.o pci.o \
skip_spaces.o lib-cmdline.o lib-ctype.o \
- alignedmem.o printk.o vsprintf.o
+ alignedmem.o printk.o vsprintf.o \
+ lib-ucs2_string.o
# include the stub's libfdt dependencies from lib/ when needed
libfdt-deps := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c \
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index f27f2e1f0019..4b51a0bf0e66 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -12,6 +12,7 @@
#include <linux/efi.h>
#include <linux/kernel.h>
#include <linux/overflow.h>
+#include <linux/ucs2_string.h>
#include <asm/efi.h>
#include <asm/setup.h>
@@ -334,81 +335,58 @@ char *efi_convert_cmdline(efi_loaded_image_t *image)
{
const efi_char16_t *options = efi_table_attr(image, load_options);
u32 options_size = efi_table_attr(image, load_options_size);
- int options_bytes = 0, safe_options_bytes = 0; /* UTF-8 bytes */
- unsigned long cmdline_addr = 0;
- const efi_char16_t *s2;
- bool in_quote = false;
+ unsigned long options_chars = 0;
+ unsigned long cmdline_bytes;
efi_status_t status;
- u32 options_chars;
+ char *cmdline_addr;
if (options_size > 0)
efi_measure_tagged_event((unsigned long)options, options_size,
EFISTUB_EVT_LOAD_OPTIONS);
efi_apply_loadoptions_quirk((const void **)&options, &options_size);
- options_chars = options_size / sizeof(efi_char16_t);
-
- if (options) {
- s2 = options;
- while (options_bytes < COMMAND_LINE_SIZE && options_chars--) {
- efi_char16_t c = *s2++;
-
- if (c < 0x80) {
- if (c == L'\0' || c == L'\n')
- break;
- if (c == L'"')
- in_quote = !in_quote;
- else if (!in_quote && isspace((char)c))
- safe_options_bytes = options_bytes;
-
- options_bytes++;
- continue;
- }
-
- /*
- * Get the number of UTF-8 bytes corresponding to a
- * UTF-16 character.
- * The first part handles everything in the BMP.
- */
- options_bytes += 2 + (c >= 0x800);
- /*
- * Add one more byte for valid surrogate pairs. Invalid
- * surrogates will be replaced with 0xfffd and take up
- * only 3 bytes.
- */
- if ((c & 0xfc00) == 0xd800) {
- /*
- * If the very last word is a high surrogate,
- * we must ignore it since we can't access the
- * low surrogate.
- */
- if (!options_chars) {
- options_bytes -= 3;
- } else if ((*s2 & 0xfc00) == 0xdc00) {
- options_bytes++;
- options_chars--;
- s2++;
- }
- }
- }
- if (options_bytes >= COMMAND_LINE_SIZE) {
- options_bytes = safe_options_bytes;
- efi_err("Command line is too long: truncated to %d bytes\n",
- options_bytes);
- }
- }
+ if (options)
+ options_chars = ucs2_strnlen(options,
+ options_size / sizeof(efi_char16_t));
- options_bytes++; /* NUL termination */
+ /* Each UCS-2 char takes up at most 3 UTF-8 bytes */
+ cmdline_bytes = min(3 * options_chars, COMMAND_LINE_SIZE - 1) + 1;
- status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, options_bytes,
+ status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, cmdline_bytes,
(void **)&cmdline_addr);
if (status != EFI_SUCCESS)
return NULL;
- snprintf((char *)cmdline_addr, options_bytes, "%.*ls",
- options_bytes - 1, options);
+ if (ucs2_as_utf8_l(cmdline_addr, options, options_chars,
+ cmdline_bytes) >= COMMAND_LINE_SIZE) {
+ /*
+ * The output fills up the entire buffer, and may have been
+ * truncated. This can only happen when options_bytes equals
+ * COMMAND_LINE_SIZE.
+ *
+ * Work backwards through the buffer to find a safe truncation
+ * point (i.e., a blank character not inside a quoted string).
+ */
+ int safe_pos[2] = {};
+ int in_quote = 0;
+
+ for (int i = COMMAND_LINE_SIZE - 1; i >= 0; i--) {
+ char c = cmdline_addr[i];
+
+ if (!c)
+ return cmdline_addr;
+ else if (c == '"')
+ in_quote ^= 1;
+ else if (!safe_pos[in_quote] && isspace(c))
+ safe_pos[in_quote] = i;
+ }
+
+ efi_err("Command line is too long: truncated to %d bytes\n",
+ safe_pos[in_quote]);
+ cmdline_addr[safe_pos[in_quote]] = '\0';
+ }
- return (char *)cmdline_addr;
+ return cmdline_addr;
}
/**
diff --git a/drivers/firmware/efi/libstub/vsprintf.c b/drivers/firmware/efi/libstub/vsprintf.c
index 71c71c222346..dba136679172 100644
--- a/drivers/firmware/efi/libstub/vsprintf.c
+++ b/drivers/firmware/efi/libstub/vsprintf.c
@@ -551,14 +551,3 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
return pos;
}
-
-int snprintf(char *buf, size_t size, const char *fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args, fmt);
- i = vsnprintf(buf, size, fmt, args);
- va_end(args);
- return i;
-}
--
2.55.0.1003.g10538fe699-goog
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 06/10] efi/libstub: Avoid efi_puts() for compile time constant strings
2026-09-09 11:55 [PATCH v2 00/10] efi/libstub: Avoid UTF-16 conversion busywork Ard Biesheuvel
` (4 preceding siblings ...)
2026-09-09 11:55 ` [PATCH v2 05/10] efi/libstub: Use ucs2_string library for UTF-16 to UTF-8 conversion Ard Biesheuvel
@ 2026-09-09 11:55 ` Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 07/10] efi/libstub: Output UTF-16 directly from vsnprintf() Ard Biesheuvel
` (3 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2026-09-09 11:55 UTC (permalink / raw)
To: linux-efi; +Cc: linux-kernel, Ard Biesheuvel, Vincent Mailhol, x86
From: Ard Biesheuvel <ardb@kernel.org>
efi_puts() performs a UTF-8 to UTF-16 conversion on its input, as the
EFI console's native character set is UTF-16.
This is pointless for compile time constant strings, since we can
simply define those as UTF-16 to begin with.
Note that efi_puts() also performs LF to CR-LF conversion, so this needs
to be taken into account as well.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
drivers/firmware/efi/libstub/gop.c | 6 +++---
drivers/firmware/efi/libstub/printk.c | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/firmware/efi/libstub/gop.c b/drivers/firmware/efi/libstub/gop.c
index 80dc8cfeb33e..6919e28ba92b 100644
--- a/drivers/firmware/efi/libstub/gop.c
+++ b/drivers/firmware/efi/libstub/gop.c
@@ -309,12 +309,12 @@ static u32 choose_mode_list(efi_graphics_output_protocol_t *gop)
efi_status_t status;
efi_printk("Available graphics modes are 0-%u\n", max_mode-1);
- efi_puts(" * = current mode\n"
- " - = unusable mode\n");
+ efi_char16_puts(L" * = current mode\r\n"
+ " - = unusable mode\r\n");
choose_mode(gop, match_list, (void *)cur_mode);
- efi_puts("\nPress any key to continue (or wait 10 seconds)\n");
+ efi_char16_puts(L"\r\nPress any key to continue (or wait 10 seconds)\r\n");
status = efi_wait_for_key(10 * EFI_USEC_PER_SEC, &key);
if (status != EFI_SUCCESS && status != EFI_TIMEOUT) {
efi_err("Unable to read key, continuing in 10 seconds\n");
diff --git a/drivers/firmware/efi/libstub/printk.c b/drivers/firmware/efi/libstub/printk.c
index bc599212c05d..f36639886d00 100644
--- a/drivers/firmware/efi/libstub/printk.c
+++ b/drivers/firmware/efi/libstub/printk.c
@@ -136,7 +136,7 @@ int efi_printk(const char *fmt, ...)
return 0;
if (loglevel >= 0)
- efi_puts("EFI stub: ");
+ efi_char16_puts(L"EFI stub: ");
fmt = printk_skip_level(fmt);
@@ -146,7 +146,7 @@ int efi_printk(const char *fmt, ...)
efi_puts(printf_buf);
if (printed >= sizeof(printf_buf)) {
- efi_puts("[Message truncated]\n");
+ efi_char16_puts(L"[Message truncated]\r\n");
return -1;
}
--
2.55.0.1003.g10538fe699-goog
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 07/10] efi/libstub: Output UTF-16 directly from vsnprintf()
2026-09-09 11:55 [PATCH v2 00/10] efi/libstub: Avoid UTF-16 conversion busywork Ard Biesheuvel
` (5 preceding siblings ...)
2026-09-09 11:55 ` [PATCH v2 06/10] efi/libstub: Avoid efi_puts() for compile time constant strings Ard Biesheuvel
@ 2026-09-09 11:55 ` Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 08/10] efi/libstub: Add support for printing human readable GUIDs Ard Biesheuvel
` (2 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2026-09-09 11:55 UTC (permalink / raw)
To: linux-efi; +Cc: linux-kernel, Ard Biesheuvel, Vincent Mailhol, x86
From: Ard Biesheuvel <ardb@kernel.org>
The only remaining users of vsnprintf() in the EFI stub are the
diagnostic printk()'s, which are emitted to the console and not recorded
for posterity.
The EFI console uses UTF-16 (or actually, UCS-2) natively, and so all
non-UTF16 strings that are emitted need to be converted. Given the
stub's vsnprintf() support for wide strings (using the %ls conversion
modifier), which uses UTF-16 to UTF-8 conversion internally, the final
conversion to UTF-16 needs to support not just plain ASCII but UTF-8 as
well.
This is all pointless, of course, and it makes more sense to use UTF-16
internally. This removes the need for UTF-16 to UTF-8 conversion in
vsnprintf(), and given that all non-wide string inputs to vsnprintf()
that exist in the stub today are compile time constant ASCII strings,
the need to convert UTF-8 to UTF-16 disappears as well.
So implement efi_vsnprintf() taking a const char *fmt as before, but
outputting a efi_char16_t[] that can be passed to the EFI console
directly, rather than via efi_puts(), leaving the latter unused and
therefore removed.
Note that efi_puts() performs LF to CR-LF conversion internally, so add
this capability to efi_vsnprintf() as well.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
drivers/firmware/efi/libstub/efistub.h | 5 +-
drivers/firmware/efi/libstub/printk.c | 91 ++-----------------
drivers/firmware/efi/libstub/vsprintf.c | 96 +++-----------------
3 files changed, 22 insertions(+), 170 deletions(-)
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index fd91fc15ec81..36056c624782 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -1078,9 +1078,10 @@ efi_status_t check_platform_features(void);
void *get_efi_config_table(efi_guid_t guid);
-/* NOTE: These functions do not print a trailing newline after the string */
void efi_char16_puts(efi_char16_t *);
-void efi_puts(const char *str);
+
+int efi_vsnprintf(efi_char16_t *buf, size_t size, const char *fmt, va_list ap,
+ bool crlf);
__printf(1, 2) int efi_printk(char const *fmt, ...);
diff --git a/drivers/firmware/efi/libstub/printk.c b/drivers/firmware/efi/libstub/printk.c
index f36639886d00..0a18cfe32528 100644
--- a/drivers/firmware/efi/libstub/printk.c
+++ b/drivers/firmware/efi/libstub/printk.c
@@ -23,98 +23,20 @@ void efi_char16_puts(efi_char16_t *str)
output_string, str);
}
-static
-u32 utf8_to_utf32(const u8 **s8)
-{
- u32 c32;
- u8 c0, cx;
- size_t clen, i;
-
- c0 = cx = *(*s8)++;
- /*
- * The position of the most-significant 0 bit gives us the length of
- * a multi-octet encoding.
- */
- for (clen = 0; cx & 0x80; ++clen)
- cx <<= 1;
- /*
- * If the 0 bit is in position 8, this is a valid single-octet
- * encoding. If the 0 bit is in position 7 or positions 1-3, the
- * encoding is invalid.
- * In either case, we just return the first octet.
- */
- if (clen < 2 || clen > 4)
- return c0;
- /* Get the bits from the first octet. */
- c32 = cx >> clen--;
- for (i = 0; i < clen; ++i) {
- /* Trailing octets must have 10 in most significant bits. */
- cx = (*s8)[i] ^ 0x80;
- if (cx & 0xc0)
- return c0;
- c32 = (c32 << 6) | cx;
- }
- /*
- * Check for validity:
- * - The character must be in the Unicode range.
- * - It must not be a surrogate.
- * - It must be encoded using the correct number of octets.
- */
- if (c32 > 0x10ffff ||
- (c32 & 0xf800) == 0xd800 ||
- clen != (c32 >= 0x80) + (c32 >= 0x800) + (c32 >= 0x10000))
- return c0;
- *s8 += clen;
- return c32;
-}
-
-/**
- * efi_puts() - Write a UTF-8 encoded string to the console
- * @str: UTF-8 encoded string
- */
-void efi_puts(const char *str)
-{
- efi_char16_t buf[128];
- size_t pos = 0, lim = ARRAY_SIZE(buf);
- const u8 *s8 = (const u8 *)str;
- u32 c32;
-
- while (*s8) {
- if (*s8 == '\n')
- buf[pos++] = L'\r';
- c32 = utf8_to_utf32(&s8);
- if (c32 < 0x10000) {
- /* Characters in plane 0 use a single word. */
- buf[pos++] = c32;
- } else {
- /*
- * Characters in other planes encode into a surrogate
- * pair.
- */
- buf[pos++] = (0xd800 - (0x10000 >> 10)) + (c32 >> 10);
- buf[pos++] = 0xdc00 + (c32 & 0x3ff);
- }
- if (*s8 == '\0' || pos >= lim - 2) {
- buf[pos] = L'\0';
- efi_char16_puts(buf);
- pos = 0;
- }
- }
-}
-
/**
* efi_printk() - Print a kernel message
* @fmt: format string
*
* The first letter of the format string is used to determine the logging level
* of the message. If the level is less then the current EFI logging level, the
- * message is suppressed. The message will be truncated to 255 bytes.
+ * message is suppressed. The message will be truncated to 255 characters
+ * (ignoring surrogates).
*
* Return: number of printed characters
*/
int efi_printk(const char *fmt, ...)
{
- char printf_buf[256];
+ efi_char16_t printf_buf[256];
va_list args;
int printed;
int loglevel = printk_get_level(fmt);
@@ -141,11 +63,12 @@ int efi_printk(const char *fmt, ...)
fmt = printk_skip_level(fmt);
va_start(args, fmt);
- printed = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args);
+ printed = efi_vsnprintf(printf_buf, ARRAY_SIZE(printf_buf), fmt, args,
+ true);
va_end(args);
- efi_puts(printf_buf);
- if (printed >= sizeof(printf_buf)) {
+ efi_char16_puts(printf_buf);
+ if (printed >= ARRAY_SIZE(printf_buf)) {
efi_char16_puts(L"[Message truncated]\r\n");
return -1;
}
diff --git a/drivers/firmware/efi/libstub/vsprintf.c b/drivers/firmware/efi/libstub/vsprintf.c
index dba136679172..bd32af6b4f4d 100644
--- a/drivers/firmware/efi/libstub/vsprintf.c
+++ b/drivers/firmware/efi/libstub/vsprintf.c
@@ -14,10 +14,14 @@
#include <linux/compiler.h>
#include <linux/ctype.h>
+#include <linux/efi.h>
#include <linux/kernel.h>
#include <linux/limits.h>
#include <linux/string.h>
#include <linux/types.h>
+#include <linux/ucs2_string.h>
+
+#include "efistub.h"
static
int skip_atoi(const char **s)
@@ -239,58 +243,6 @@ char get_sign(long long *num, int flags)
return 0;
}
-static
-size_t utf16s_utf8nlen(const u16 *s16, size_t maxlen)
-{
- size_t len, clen;
-
- for (len = 0; len < maxlen && *s16; len += clen) {
- u16 c0 = *s16++;
-
- /* First, get the length for a BMP character */
- clen = 1 + (c0 >= 0x80) + (c0 >= 0x800);
- if (len + clen > maxlen)
- break;
- /*
- * If this is a high surrogate, and we're already at maxlen, we
- * can't include the character if it's a valid surrogate pair.
- * Avoid accessing one extra word just to check if it's valid
- * or not.
- */
- if ((c0 & 0xfc00) == 0xd800) {
- if (len + clen == maxlen)
- break;
- if ((*s16 & 0xfc00) == 0xdc00) {
- ++s16;
- ++clen;
- }
- }
- }
-
- return len;
-}
-
-static
-u32 utf16_to_utf32(const u16 **s16)
-{
- u16 c0, c1;
-
- c0 = *(*s16)++;
- /* not a surrogate */
- if ((c0 & 0xf800) != 0xd800)
- return c0;
- /* invalid: low surrogate instead of high */
- if (c0 & 0x0400)
- return 0xfffd;
- c1 = **s16;
- /* invalid: missing low surrogate */
- if ((c1 & 0xfc00) != 0xdc00)
- return 0xfffd;
- /* valid surrogate pair */
- ++(*s16);
- return (0x10000 - (0xd800 << 10) - 0xdc00) + (c0 << 10) + c1;
-}
-
#define PUTC(c) \
do { \
if (pos < size) \
@@ -298,7 +250,8 @@ do { \
++pos; \
} while (0);
-int vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
+int efi_vsnprintf(efi_char16_t *buf, size_t size, const char *fmt, va_list ap,
+ bool crlf)
{
/* The maximum space required is to print a 64-bit number in octal */
char tmp[(sizeof(unsigned long long) * 8 + 2) / 3];
@@ -336,6 +289,8 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
for (pos = 0; *fmt; ++fmt) {
if (*fmt != '%' || *++fmt == '%') {
+ if (crlf && *fmt == '\n')
+ PUTC('\r');
PUTC(*fmt);
continue;
}
@@ -400,7 +355,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
else if (qualifier == 'l') {
wstring:
flags |= WIDE;
- precision = len = utf16s_utf8nlen((const u16 *)s, precision);
+ precision = len = ucs2_strnlen((const u16 *)s, precision);
goto output;
}
precision = len = strnlen(s, precision);
@@ -505,36 +460,9 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
if (flags & WIDE) {
const u16 *ws = (const u16 *)s;
- while (len-- > 0) {
- u32 c32 = utf16_to_utf32(&ws);
- u8 *s8;
- size_t clen;
-
- if (c32 < 0x80) {
- PUTC(c32);
- continue;
- }
-
- /* Number of trailing octets */
- clen = 1 + (c32 >= 0x800) + (c32 >= 0x10000);
-
- len -= clen;
- s8 = (u8 *)&buf[pos];
-
- /* Avoid writing partial character */
- PUTC('\0');
- pos += clen;
- if (pos >= size)
- continue;
-
- /* Set high bits of leading octet */
- *s8 = (0xf00 >> 1) >> clen;
- /* Write trailing octets in reverse order */
- for (s8 += clen; clen; --clen, c32 >>= 6)
- *s8-- = 0x80 | (c32 & 0x3f);
- /* Set low bits of leading octet */
- *s8 |= c32;
- }
+ if (pos < size)
+ memcpy(&buf[pos], ws, min(len, size - pos) * sizeof(*ws));
+ pos += len;
} else {
while (len-- > 0)
PUTC(*s++);
--
2.55.0.1003.g10538fe699-goog
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 08/10] efi/libstub: Add support for printing human readable GUIDs
2026-09-09 11:55 [PATCH v2 00/10] efi/libstub: Avoid UTF-16 conversion busywork Ard Biesheuvel
` (6 preceding siblings ...)
2026-09-09 11:55 ` [PATCH v2 07/10] efi/libstub: Output UTF-16 directly from vsnprintf() Ard Biesheuvel
@ 2026-09-09 11:55 ` Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 09/10] efi/libstub: Add efi_snprintf() to construct wide strings Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 10/10] efi/libstub: add initial Boot Loader Interface support Ard Biesheuvel
9 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2026-09-09 11:55 UTC (permalink / raw)
To: linux-efi; +Cc: linux-kernel, Ard Biesheuvel, Vincent Mailhol, x86
From: Ard Biesheuvel <ardb@kernel.org>
Add support for the %pUl printk conversion specifier, which takes a
pointer to a GUID and prints it in the usual format:
aaaaaaaa-bbbb-cccc-dddd-dddddddddddd
Co-developed-by: Vincent Mailhol <mailhol@kernel.org>
Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
drivers/firmware/efi/libstub/vsprintf.c | 40 +++++++++++++++++---
1 file changed, 35 insertions(+), 5 deletions(-)
diff --git a/drivers/firmware/efi/libstub/vsprintf.c b/drivers/firmware/efi/libstub/vsprintf.c
index bd32af6b4f4d..7f6b891a338a 100644
--- a/drivers/firmware/efi/libstub/vsprintf.c
+++ b/drivers/firmware/efi/libstub/vsprintf.c
@@ -113,6 +113,9 @@ char *put_dec(char *end, unsigned long long n)
return p;
}
+/* we are called with base 8, 10 or 16, only, thus don't need "G..." */
+static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
+
static
char *number(char *end, unsigned long long num, int base, char locase)
{
@@ -121,9 +124,6 @@ char *number(char *end, unsigned long long num, int base, char locase)
* produces same digits or (maybe lowercased) letters
*/
- /* we are called with base 8, 10 or 16, only, thus don't need "G..." */
- static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
-
switch (base) {
case 10:
if (num != 0)
@@ -144,6 +144,29 @@ char *number(char *end, unsigned long long num, int base, char locase)
return end;
}
+static char *guid_to_str(const efi_guid_t *guid, char *out, char locase)
+{
+ static const u8 guid_index[UUID_SIZE] = {
+ 3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15,
+ };
+
+ for (int i = 0, p = 0; i < ARRAY_SIZE(guid_index); i++) {
+ u8 byte = guid->b[guid_index[i]];
+
+ out[p++] = locase | digits[byte >> 4];
+ out[p++] = locase | digits[byte & 0xf];
+
+ switch (i) {
+ case 3:
+ case 5:
+ case 7:
+ case 9:
+ out[p++] = '-';
+ }
+ }
+ return out;
+}
+
#define ZEROPAD 1 /* pad with zero */
#define SIGN 2 /* unsigned/signed long */
#define PLUS 4 /* show plus */
@@ -253,8 +276,7 @@ do { \
int efi_vsnprintf(efi_char16_t *buf, size_t size, const char *fmt, va_list ap,
bool crlf)
{
- /* The maximum space required is to print a 64-bit number in octal */
- char tmp[(sizeof(unsigned long long) * 8 + 2) / 3];
+ char tmp[UUID_STRING_LEN];
char *tmp_end = &tmp[ARRAY_SIZE(tmp)];
long long num;
int base;
@@ -367,6 +389,14 @@ int efi_vsnprintf(efi_char16_t *buf, size_t size, const char *fmt, va_list ap,
break;
case 'p':
+ if (fmt[1] == 'U' && (fmt[2] | 0x20) == 'l') {
+ flags &= LEFT;
+ s = guid_to_str(va_arg(args, efi_guid_t *), tmp, fmt[2] & 0x20);
+ precision = len = UUID_STRING_LEN;
+ fmt += 2;
+ goto output;
+ }
+
if (precision < 0)
precision = 2 * sizeof(void *);
fallthrough;
--
2.55.0.1003.g10538fe699-goog
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 09/10] efi/libstub: Add efi_snprintf() to construct wide strings
2026-09-09 11:55 [PATCH v2 00/10] efi/libstub: Avoid UTF-16 conversion busywork Ard Biesheuvel
` (7 preceding siblings ...)
2026-09-09 11:55 ` [PATCH v2 08/10] efi/libstub: Add support for printing human readable GUIDs Ard Biesheuvel
@ 2026-09-09 11:55 ` Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 10/10] efi/libstub: add initial Boot Loader Interface support Ard Biesheuvel
9 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2026-09-09 11:55 UTC (permalink / raw)
To: linux-efi; +Cc: linux-kernel, Ard Biesheuvel, Vincent Mailhol, x86
From: Ard Biesheuvel <ardb@kernel.org>
The native EFI character set is UTF-16 (or in practice, UCS-2).
Implement efi_snprintf() to construct UTF-16 strings using printf style
templates. This will be used in a subsequent patch to set the
LoaderDevicePartUUID EFI variable.
Link: https://lore.kernel.org/all/20260903-efi_stub_bli-v2-1-dbf7ba915117@kernel.org/
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
drivers/firmware/efi/libstub/efistub.h | 1 +
drivers/firmware/efi/libstub/vsprintf.c | 11 +++++++++++
2 files changed, 12 insertions(+)
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index 36056c624782..880c1d0c464b 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -1084,6 +1084,7 @@ int efi_vsnprintf(efi_char16_t *buf, size_t size, const char *fmt, va_list ap,
bool crlf);
__printf(1, 2) int efi_printk(char const *fmt, ...);
+__printf(3, 4) int efi_snprintf(efi_char16_t *buf, size_t size, const char *fmt, ...);
void efi_free(unsigned long size, unsigned long addr);
DEFINE_FREE(efi_pool, void *, if (_T) efi_bs_call(free_pool, _T));
diff --git a/drivers/firmware/efi/libstub/vsprintf.c b/drivers/firmware/efi/libstub/vsprintf.c
index 7f6b891a338a..34a19495dace 100644
--- a/drivers/firmware/efi/libstub/vsprintf.c
+++ b/drivers/firmware/efi/libstub/vsprintf.c
@@ -509,3 +509,14 @@ int efi_vsnprintf(efi_char16_t *buf, size_t size, const char *fmt, va_list ap,
return pos;
}
+
+int efi_snprintf(efi_char16_t *buf, size_t size, const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args, fmt);
+ i = efi_vsnprintf(buf, size, fmt, args, false);
+ va_end(args);
+ return i;
+}
--
2.55.0.1003.g10538fe699-goog
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 10/10] efi/libstub: add initial Boot Loader Interface support
2026-09-09 11:55 [PATCH v2 00/10] efi/libstub: Avoid UTF-16 conversion busywork Ard Biesheuvel
` (8 preceding siblings ...)
2026-09-09 11:55 ` [PATCH v2 09/10] efi/libstub: Add efi_snprintf() to construct wide strings Ard Biesheuvel
@ 2026-09-09 11:55 ` Ard Biesheuvel
9 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2026-09-09 11:55 UTC (permalink / raw)
To: linux-efi; +Cc: linux-kernel, Ard Biesheuvel, Vincent Mailhol, x86
From: Vincent Mailhol <mailhol@kernel.org>
The Boot Loader Interface (BLI) [1] defines EFI variables that expose
boot loader state to the running OS. LoaderInfo identifies the boot
loader, while LoaderDevicePartUUID records the GPT partition UUID of
the partition containing it.
LoaderDevicePartUUID is used, for example, by systemd-gpt-auto-generator
[2] to identify the disk the boot loader was launched from and
automatically detect and mount partitions on it.
GRUB [3] and systemd-boot [4] populate these variables, but when the
kernel is started directly by EFI firmware, there is no conventional
external boot loader to provide them. In that case, because the EFI stub
performs the boot loader role, it should provide the variables itself.
Use LoaderInfo as a sentinel: if it is already set by an earlier boot
stage or cannot be set, bail out. Otherwise, populate the other BLI
variables.
Parse the loaded image device path, extract the GUID signature from its
GPT HD() node and publish it under the Linux loader entry vendor GUID as
the volatile LoaderDevicePartUUID EFI variable.
Install the efi_bli_set_variables() hook in both the generic efi-stub.c
path and the x86-specific x86-stub.c path.
[1] The Boot Loader Interface
Link: https://systemd.io/BOOT_LOADER_INTERFACE/
[2] systemd-gpt-auto-generator
Link: https://www.freedesktop.org/software/systemd/man/latest/systemd-gpt-auto-generator.html
[3] GRUB -- §16.2 bli
Link: https://www.gnu.org/software/grub/manual/grub/html_node/bli_005fmodule.html
[4] systemd -- systemd-boot UEFI Boot Manager
Link: https://github.com/systemd/systemd/blob/main/docs/BOOT.md?plain=1#L102
Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
[ardb: - constify 'image' pointer parameter
- pass efi_guid_t* to efi_snprintf()]
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
drivers/firmware/efi/libstub/Makefile | 2 +-
drivers/firmware/efi/libstub/bli.c | 87 ++++++++++++++++++++
drivers/firmware/efi/libstub/efi-stub.c | 1 +
drivers/firmware/efi/libstub/efistub.h | 2 +
drivers/firmware/efi/libstub/x86-stub.c | 1 +
include/linux/efi.h | 22 +++++
6 files changed, 114 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index 12c0c7deb5cb..564773c89d14 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -66,7 +66,7 @@ KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o \
file.o mem.o random.o randomalloc.o pci.o \
skip_spaces.o lib-cmdline.o lib-ctype.o \
- alignedmem.o printk.o vsprintf.o \
+ alignedmem.o printk.o vsprintf.o bli.o \
lib-ucs2_string.o
# include the stub's libfdt dependencies from lib/ when needed
diff --git a/drivers/firmware/efi/libstub/bli.c b/drivers/firmware/efi/libstub/bli.c
new file mode 100644
index 000000000000..b2407f63b743
--- /dev/null
+++ b/drivers/firmware/efi/libstub/bli.c
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <generated/utsrelease.h>
+
+#include <linux/efi.h>
+#include <linux/errno.h>
+#include <linux/unaligned.h>
+
+#include "efistub.h"
+
+static efi_guid_t loader_entry_guid = LINUX_EFI_LOADER_ENTRY_GUID;
+
+static const struct efi_hd_dev_path *
+efi_bli_find_hd_node(const struct efi_dev_path *path)
+{
+ const struct efi_dev_path *node;
+ u16 node_len;
+
+ for (node = path;
+ node->header.type != EFI_DEV_END_PATH &&
+ node->header.type != EFI_DEV_END_PATH2;
+ node = (const void *)node + node_len) {
+ node_len = get_unaligned_le16(&node->header.length);
+
+ if (node_len < sizeof(node->header))
+ return NULL;
+
+ if (node->header.type != EFI_DEV_MEDIA ||
+ node->header.sub_type != EFI_DEV_MEDIA_HARD_DRIVE)
+ continue;
+
+ if (node_len < sizeof(node->hd))
+ return NULL;
+
+ if (node->hd.partition_format != EFI_HD_PARTITION_FORMAT_GPT ||
+ node->hd.signature_type != EFI_HD_SIGNATURE_TYPE_GUID)
+ continue;
+
+ return &node->hd;
+ }
+
+ return NULL;
+}
+
+static void efi_bli_populate_loader_part_uuid(const efi_loaded_image_t *image)
+{
+ static efi_guid_t device_path_guid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+ efi_char16_t partuuid[UUID_STRING_LEN + 1];
+ const struct efi_hd_dev_path *hd_node;
+ const struct efi_dev_path *path;
+
+ if (efi_bs_call(handle_protocol, efi_table_attr(image, device_handle),
+ &device_path_guid, (void **)&path) != EFI_SUCCESS)
+ return;
+
+ hd_node = efi_bli_find_hd_node(path);
+ if (!hd_node)
+ return;
+
+ if (efi_snprintf(partuuid, ARRAY_SIZE(partuuid), "%pUl",
+ &hd_node->signature) != UUID_STRING_LEN)
+ return;
+
+ set_efi_var(L"LoaderDevicePartUUID", &loader_entry_guid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(partuuid), partuuid);
+}
+
+void efi_bli_set_variables(const efi_loaded_image_t *image)
+{
+ static efi_char16_t loader_info[] = L"Linux EFI stub " UTS_RELEASE;
+ unsigned long size = 0;
+
+ if (!image)
+ return;
+
+ if (get_efi_var(L"LoaderInfo", &loader_entry_guid,
+ NULL, &size, NULL) != EFI_NOT_FOUND)
+ return;
+
+ if (set_efi_var(L"LoaderInfo", &loader_entry_guid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(loader_info), loader_info) != EFI_SUCCESS)
+ return;
+
+ efi_bli_populate_loader_part_uuid(image);
+}
diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c
index 42d6073bcd06..2a95f4ea104a 100644
--- a/drivers/firmware/efi/libstub/efi-stub.c
+++ b/drivers/firmware/efi/libstub/efi-stub.c
@@ -165,6 +165,7 @@ efi_status_t efi_stub_common(efi_handle_t handle,
dpy = setup_primary_display();
efi_retrieve_eventlog();
+ efi_bli_set_variables(image);
/* Ask the firmware to clear memory on unclean shutdown */
efi_enable_reset_attack_mitigation();
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index 880c1d0c464b..4f9e7ae28b6c 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -1072,6 +1072,8 @@ efi_status_t efi_random_alloc(unsigned long size, unsigned long align,
int memory_type, unsigned long alloc_min,
unsigned long alloc_max);
+void efi_bli_set_variables(const efi_loaded_image_t *image);
+
efi_status_t efi_random_get_seed(void);
efi_status_t check_platform_features(void);
diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c
index cef32e2c82d8..b762f7f37f28 100644
--- a/drivers/firmware/efi/libstub/x86-stub.c
+++ b/drivers/firmware/efi/libstub/x86-stub.c
@@ -1014,6 +1014,7 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
efi_random_get_seed();
efi_retrieve_eventlog();
+ efi_bli_set_variables(image);
setup_graphics(boot_params);
diff --git a/include/linux/efi.h b/include/linux/efi.h
index c35446a0b66f..ecb34be37a87 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -957,6 +957,17 @@ extern int efi_status_to_err(efi_status_t status);
#define EFI_DEV_END_INSTANCE 0x01
#define EFI_DEV_END_ENTIRE 0xFF
+enum efi_hd_partition_format {
+ EFI_HD_PARTITION_FORMAT_MBR = 1,
+ EFI_HD_PARTITION_FORMAT_GPT,
+};
+
+enum efi_hd_signature_type {
+ EFI_HD_SIGNATURE_TYPE_NONE,
+ EFI_HD_SIGNATURE_TYPE_MBR,
+ EFI_HD_SIGNATURE_TYPE_GUID,
+};
+
struct efi_generic_dev_path {
u8 type;
u8 sub_type;
@@ -988,6 +999,16 @@ struct efi_rel_offset_dev_path {
u64 ending_offset;
} __packed;
+struct efi_hd_dev_path {
+ struct efi_generic_dev_path header;
+ u32 partition_number;
+ u64 partition_start;
+ u64 partition_size;
+ efi_guid_t signature;
+ u8 partition_format;
+ u8 signature_type;
+} __packed;
+
struct efi_mem_mapped_dev_path {
struct efi_generic_dev_path header;
u32 memory_type;
@@ -1007,6 +1028,7 @@ struct efi_dev_path {
struct efi_pci_dev_path pci;
struct efi_vendor_dev_path vendor;
struct efi_rel_offset_dev_path rel_offset;
+ struct efi_hd_dev_path hd;
};
} __packed;
--
2.55.0.1003.g10538fe699-goog
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 01/10] x86/boot: Drop pointless re-implementation of panic()
2026-09-09 11:55 ` [PATCH v2 01/10] x86/boot: Drop pointless re-implementation of panic() Ard Biesheuvel
@ 2026-09-09 19:14 ` Borislav Petkov
2026-09-09 20:43 ` Ard Biesheuvel
0 siblings, 1 reply; 15+ messages in thread
From: Borislav Petkov @ 2026-09-09 19:14 UTC (permalink / raw)
To: Ard Biesheuvel, Kiryl Shutsemau
Cc: linux-efi, linux-kernel, Ard Biesheuvel, Vincent Mailhol, x86
On Wed, Sep 09, 2026 at 01:55:32PM +0200, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb@kernel.org>
>
> The decompressor has its own implementation of panic(), which is based
> on the vsnprintf() routine provided by the EFI stub.
>
> Relying on the EFI stub from code that does not execute in the context
> of the EFI boot services is a bad idea. It is also completely pointless
> in this case, given that the only user of this version of panic() only
> passes a compile time constant string, without any printf conversions.
>
> So use error() instead of panic() in that case, and drop the panic()
> implementation entirely. This is needed so that the EFI stub's
> vsnprintf() can be modified in a manner that is incompatible with the
> expectations of this caller.
>
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> ---
> arch/x86/boot/compressed/error.c | 19 -------------------
> arch/x86/boot/compressed/error.h | 1 -
> arch/x86/boot/compressed/mem.c | 2 +-
> 3 files changed, 1 insertion(+), 21 deletions(-)
>
> diff --git a/arch/x86/boot/compressed/error.c b/arch/x86/boot/compressed/error.c
> index 19a8251de506..ce5ed7d8265e 100644
> --- a/arch/x86/boot/compressed/error.c
> +++ b/arch/x86/boot/compressed/error.c
> @@ -22,22 +22,3 @@ void error(char *m)
> while (1)
> asm("hlt");
> }
> -
> -/* EFI libstub provides vsnprintf() */
> -#ifdef CONFIG_EFI_STUB
> -void panic(const char *fmt, ...)
So this thing appeared magically in v8 of the TDX unaccepted memory patches
and I don't think we questioned it back then.
v7's tdx_accept_memory() does error():
https://lore.kernel.org/all/20220614120231.48165-15-kirill.shutemov@linux.intel.com/
and v8 started doing panic():
+void tdx_accept_memory(phys_addr_t start, phys_addr_t end)
+{
+ if (!tdx_enc_status_changed_phys(start, end, true))
+ panic("Accepting memory failed: %#llx-%#llx\n", start, end);
+}
https://lore.kernel.org/all/20221207014933.8435-15-kirill.shutemov@linux.intel.com/
and it switched to it being a vsnprintf() wrapper because it wanted to dump
start and end perhaps.
But then it ended up dropping the params in v13 and landed upstream with
a single string as an argument.
Anyway, adding Kiryl/Kirill for comment and leaving in the rest for reference.
> -{
> - static char buf[1024];
> - va_list args;
> - int len;
> -
> - va_start(args, fmt);
> - len = vsnprintf(buf, sizeof(buf), fmt, args);
> - va_end(args);
> -
> - if (len && buf[len - 1] == '\n')
> - buf[len - 1] = '\0';
> -
> - error(buf);
> -}
> -#endif
> diff --git a/arch/x86/boot/compressed/error.h b/arch/x86/boot/compressed/error.h
> index 31f9e080d61a..87062dea9a20 100644
> --- a/arch/x86/boot/compressed/error.h
> +++ b/arch/x86/boot/compressed/error.h
> @@ -6,6 +6,5 @@
>
> void warn(const char *m);
> void error(char *m) __noreturn;
> -void panic(const char *fmt, ...) __noreturn __cold;
>
> #endif /* BOOT_COMPRESSED_ERROR_H */
> diff --git a/arch/x86/boot/compressed/mem.c b/arch/x86/boot/compressed/mem.c
> index 0e9f84ab4bdc..e1c017b55184 100644
> --- a/arch/x86/boot/compressed/mem.c
> +++ b/arch/x86/boot/compressed/mem.c
> @@ -37,7 +37,7 @@ void arch_accept_memory(phys_addr_t start, phys_addr_t end)
> /* Platform-specific memory-acceptance call goes here */
> if (early_is_tdx_guest()) {
> if (!tdx_accept_memory(start, end))
> - panic("TDX: Failed to accept memory\n");
> + error("TDX: Failed to accept memory\n");
> } else if (early_is_sevsnp_guest()) {
> snp_accept_memory(start, end);
> } else {
> --
> 2.55.0.1003.g10538fe699-goog
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 01/10] x86/boot: Drop pointless re-implementation of panic()
2026-09-09 19:14 ` Borislav Petkov
@ 2026-09-09 20:43 ` Ard Biesheuvel
2026-09-10 13:12 ` Kiryl Shutsemau
0 siblings, 1 reply; 15+ messages in thread
From: Ard Biesheuvel @ 2026-09-09 20:43 UTC (permalink / raw)
To: Borislav Petkov, Ard Biesheuvel, Kiryl Shutsemau
Cc: linux-efi, linux-kernel, Vincent Mailhol, x86
On Wed, 9 Sep 2026, at 21:14, Borislav Petkov wrote:
> On Wed, Sep 09, 2026 at 01:55:32PM +0200, Ard Biesheuvel wrote:
>> From: Ard Biesheuvel <ardb@kernel.org>
>>
>> The decompressor has its own implementation of panic(), which is based
>> on the vsnprintf() routine provided by the EFI stub.
>>
>> Relying on the EFI stub from code that does not execute in the context
>> of the EFI boot services is a bad idea. It is also completely pointless
>> in this case, given that the only user of this version of panic() only
>> passes a compile time constant string, without any printf conversions.
>>
>> So use error() instead of panic() in that case, and drop the panic()
>> implementation entirely. This is needed so that the EFI stub's
>> vsnprintf() can be modified in a manner that is incompatible with the
>> expectations of this caller.
>>
>> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
>> ---
>> arch/x86/boot/compressed/error.c | 19 -------------------
>> arch/x86/boot/compressed/error.h | 1 -
>> arch/x86/boot/compressed/mem.c | 2 +-
>> 3 files changed, 1 insertion(+), 21 deletions(-)
>>
>> diff --git a/arch/x86/boot/compressed/error.c b/arch/x86/boot/compressed/error.c
>> index 19a8251de506..ce5ed7d8265e 100644
>> --- a/arch/x86/boot/compressed/error.c
>> +++ b/arch/x86/boot/compressed/error.c
>> @@ -22,22 +22,3 @@ void error(char *m)
>> while (1)
>> asm("hlt");
>> }
>> -
>> -/* EFI libstub provides vsnprintf() */
>> -#ifdef CONFIG_EFI_STUB
>> -void panic(const char *fmt, ...)
>
> So this thing appeared magically in v8 of the TDX unaccepted memory patches
> and I don't think we questioned it back then.
>
> v7's tdx_accept_memory() does error():
>
> https://lore.kernel.org/all/20220614120231.48165-15-kirill.shutemov@linux.intel.com/
>
> and v8 started doing panic():
>
> +void tdx_accept_memory(phys_addr_t start, phys_addr_t end)
> +{
> + if (!tdx_enc_status_changed_phys(start, end, true))
> + panic("Accepting memory failed: %#llx-%#llx\n", start, end);
> +}
>
> https://lore.kernel.org/all/20221207014933.8435-15-kirill.shutemov@linux.intel.com/
>
> and it switched to it being a vsnprintf() wrapper because it wanted to dump
> start and end perhaps.
>
> But then it ended up dropping the params in v13 and landed upstream with
> a single string as an argument.
>
> Anyway, adding Kiryl/Kirill for comment and leaving in the rest for reference.
>
Looking at that v13, it seems the panic() call was added to
arch/x86/coco/tdx/tdx-shared.c, which was shared between the kernel proper and
the decompressorat the time, and so a panic() implementation was needed in the
decompressor too. But that is no longer the case.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 01/10] x86/boot: Drop pointless re-implementation of panic()
2026-09-09 20:43 ` Ard Biesheuvel
@ 2026-09-10 13:12 ` Kiryl Shutsemau
2026-09-11 7:32 ` Ard Biesheuvel
0 siblings, 1 reply; 15+ messages in thread
From: Kiryl Shutsemau @ 2026-09-10 13:12 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Borislav Petkov, Ard Biesheuvel, linux-efi, linux-kernel,
Vincent Mailhol, x86
On Wed, Sep 09, 2026 at 10:43:23PM +0200, Ard Biesheuvel wrote:
>
> On Wed, 9 Sep 2026, at 21:14, Borislav Petkov wrote:
> > On Wed, Sep 09, 2026 at 01:55:32PM +0200, Ard Biesheuvel wrote:
> >> From: Ard Biesheuvel <ardb@kernel.org>
> >>
> >> The decompressor has its own implementation of panic(), which is based
> >> on the vsnprintf() routine provided by the EFI stub.
> >>
> >> Relying on the EFI stub from code that does not execute in the context
> >> of the EFI boot services is a bad idea. It is also completely pointless
> >> in this case, given that the only user of this version of panic() only
> >> passes a compile time constant string, without any printf conversions.
> >>
> >> So use error() instead of panic() in that case, and drop the panic()
> >> implementation entirely. This is needed so that the EFI stub's
> >> vsnprintf() can be modified in a manner that is incompatible with the
> >> expectations of this caller.
> >>
> >> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> >> ---
> >> arch/x86/boot/compressed/error.c | 19 -------------------
> >> arch/x86/boot/compressed/error.h | 1 -
> >> arch/x86/boot/compressed/mem.c | 2 +-
> >> 3 files changed, 1 insertion(+), 21 deletions(-)
> >>
> >> diff --git a/arch/x86/boot/compressed/error.c b/arch/x86/boot/compressed/error.c
> >> index 19a8251de506..ce5ed7d8265e 100644
> >> --- a/arch/x86/boot/compressed/error.c
> >> +++ b/arch/x86/boot/compressed/error.c
> >> @@ -22,22 +22,3 @@ void error(char *m)
> >> while (1)
> >> asm("hlt");
> >> }
> >> -
> >> -/* EFI libstub provides vsnprintf() */
> >> -#ifdef CONFIG_EFI_STUB
> >> -void panic(const char *fmt, ...)
> >
> > So this thing appeared magically in v8 of the TDX unaccepted memory patches
> > and I don't think we questioned it back then.
> >
> > v7's tdx_accept_memory() does error():
> >
> > https://lore.kernel.org/all/20220614120231.48165-15-kirill.shutemov@linux.intel.com/
> >
> > and v8 started doing panic():
> >
> > +void tdx_accept_memory(phys_addr_t start, phys_addr_t end)
> > +{
> > + if (!tdx_enc_status_changed_phys(start, end, true))
> > + panic("Accepting memory failed: %#llx-%#llx\n", start, end);
> > +}
> >
> > https://lore.kernel.org/all/20221207014933.8435-15-kirill.shutemov@linux.intel.com/
> >
> > and it switched to it being a vsnprintf() wrapper because it wanted to dump
> > start and end perhaps.
> >
> > But then it ended up dropping the params in v13 and landed upstream with
> > a single string as an argument.
> >
> > Anyway, adding Kiryl/Kirill for comment and leaving in the rest for reference.
> >
>
> Looking at that v13, it seems the panic() call was added to
> arch/x86/coco/tdx/tdx-shared.c, which was shared between the kernel proper and
> the decompressorat the time, and so a panic() implementation was needed in the
> decompressor too. But that is no longer the case.
Right. I don't mind dropping this panic() from the decompressor. The
range was already gone since v13 and I never saw the error trigger
anyway.
Acked-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
--
Kiryl Shutsemau / Kirill A. Shutemov
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 01/10] x86/boot: Drop pointless re-implementation of panic()
2026-09-10 13:12 ` Kiryl Shutsemau
@ 2026-09-11 7:32 ` Ard Biesheuvel
0 siblings, 0 replies; 15+ messages in thread
From: Ard Biesheuvel @ 2026-09-11 7:32 UTC (permalink / raw)
To: Kiryl Shutsemau
Cc: Borislav Petkov, Ard Biesheuvel, linux-efi, linux-kernel,
Vincent Mailhol, x86
On Thu, 10 Sep 2026, at 15:12, Kiryl Shutsemau wrote:
> On Wed, Sep 09, 2026 at 10:43:23PM +0200, Ard Biesheuvel wrote:
>>
>> On Wed, 9 Sep 2026, at 21:14, Borislav Petkov wrote:
>> > On Wed, Sep 09, 2026 at 01:55:32PM +0200, Ard Biesheuvel wrote:
>> >> From: Ard Biesheuvel <ardb@kernel.org>
>> >>
>> >> The decompressor has its own implementation of panic(), which is based
>> >> on the vsnprintf() routine provided by the EFI stub.
>> >>
>> >> Relying on the EFI stub from code that does not execute in the context
>> >> of the EFI boot services is a bad idea. It is also completely pointless
>> >> in this case, given that the only user of this version of panic() only
>> >> passes a compile time constant string, without any printf conversions.
>> >>
>> >> So use error() instead of panic() in that case, and drop the panic()
>> >> implementation entirely. This is needed so that the EFI stub's
>> >> vsnprintf() can be modified in a manner that is incompatible with the
>> >> expectations of this caller.
>> >>
>> >> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
>> >> ---
>> >> arch/x86/boot/compressed/error.c | 19 -------------------
>> >> arch/x86/boot/compressed/error.h | 1 -
>> >> arch/x86/boot/compressed/mem.c | 2 +-
>> >> 3 files changed, 1 insertion(+), 21 deletions(-)
>> >>
>> >> diff --git a/arch/x86/boot/compressed/error.c b/arch/x86/boot/compressed/error.c
>> >> index 19a8251de506..ce5ed7d8265e 100644
>> >> --- a/arch/x86/boot/compressed/error.c
>> >> +++ b/arch/x86/boot/compressed/error.c
>> >> @@ -22,22 +22,3 @@ void error(char *m)
>> >> while (1)
>> >> asm("hlt");
>> >> }
>> >> -
>> >> -/* EFI libstub provides vsnprintf() */
>> >> -#ifdef CONFIG_EFI_STUB
>> >> -void panic(const char *fmt, ...)
>> >
>> > So this thing appeared magically in v8 of the TDX unaccepted memory patches
>> > and I don't think we questioned it back then.
>> >
>> > v7's tdx_accept_memory() does error():
>> >
>> > https://lore.kernel.org/all/20220614120231.48165-15-kirill.shutemov@linux.intel.com/
>> >
>> > and v8 started doing panic():
>> >
>> > +void tdx_accept_memory(phys_addr_t start, phys_addr_t end)
>> > +{
>> > + if (!tdx_enc_status_changed_phys(start, end, true))
>> > + panic("Accepting memory failed: %#llx-%#llx\n", start, end);
>> > +}
>> >
>> > https://lore.kernel.org/all/20221207014933.8435-15-kirill.shutemov@linux.intel.com/
>> >
>> > and it switched to it being a vsnprintf() wrapper because it wanted to dump
>> > start and end perhaps.
>> >
>> > But then it ended up dropping the params in v13 and landed upstream with
>> > a single string as an argument.
>> >
>> > Anyway, adding Kiryl/Kirill for comment and leaving in the rest for reference.
>> >
>>
>> Looking at that v13, it seems the panic() call was added to
>> arch/x86/coco/tdx/tdx-shared.c, which was shared between the kernel proper and
>> the decompressorat the time, and so a panic() implementation was needed in the
>> decompressor too. But that is no longer the case.
>
> Right. I don't mind dropping this panic() from the decompressor. The
> range was already gone since v13 and I never saw the error trigger
> anyway.
>
> Acked-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
>
Thanks. Can this be applied as a fix please? I need it to base efi/next
on it for the next cycle.
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2026-09-11 7:32 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-09 11:55 [PATCH v2 00/10] efi/libstub: Avoid UTF-16 conversion busywork Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 01/10] x86/boot: Drop pointless re-implementation of panic() Ard Biesheuvel
2026-09-09 19:14 ` Borislav Petkov
2026-09-09 20:43 ` Ard Biesheuvel
2026-09-10 13:12 ` Kiryl Shutsemau
2026-09-11 7:32 ` Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 02/10] lib/ucs2_string: Drop arbitrary input size limit and associated WARN() Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 03/10] lib/ucs2_string: Suppress modinfo when __DISABLE_EXPORTS is set Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 04/10] lib/ucs2_string: Split out ucs2_as_utf8_l() taking a separate limit Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 05/10] efi/libstub: Use ucs2_string library for UTF-16 to UTF-8 conversion Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 06/10] efi/libstub: Avoid efi_puts() for compile time constant strings Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 07/10] efi/libstub: Output UTF-16 directly from vsnprintf() Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 08/10] efi/libstub: Add support for printing human readable GUIDs Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 09/10] efi/libstub: Add efi_snprintf() to construct wide strings Ard Biesheuvel
2026-09-09 11:55 ` [PATCH v2 10/10] efi/libstub: add initial Boot Loader Interface support Ard Biesheuvel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®