* [PATCH 1/3] efi/libstub: move direct GUID references to static storage
2026-09-03 21:25 [PATCH 0/3] efi/libstub: reduce size by optimizing GUID storage Vincent Mailhol
@ 2026-09-03 21:25 ` Vincent Mailhol
2026-09-03 21:25 ` [PATCH 2/3] efi/libstub: make local GUID variables static Vincent Mailhol
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Vincent Mailhol @ 2026-09-03 21:25 UTC (permalink / raw)
To: Ard Biesheuvel, Ilias Apalodimas; +Cc: linux-efi, linux-kernel, Vincent Mailhol
Some EFI stub call sites pass the address of a GUID macro directly to
EFI boot services. With gcc, this makes the compiler materialize the
GUID data at the call site, which is wasteful in the size-sensitive EFI
stub.
For example, consider this program:
#include <linux/efi.h>
#define GUID \
EFI_GUID(0xaaaaaaaa, 0xbbbb, 0xcccc, \
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd)
void foo(const efi_guid_t *guid);
void guid_direct(void)
{
foo(&GUID);
}
void guid_static(void)
{
static efi_guid_t guid = GUID;
foo(&guid);
}
For guid_direct(), gcc materializes the GUID on the stack:
0: f3 0f 1e fa endbr64
4: 48 b8 aa aa aa aa bb movabs $0xccccbbbbaaaaaaaa,%rax
b: bb cc cc
e: 48 83 ec 18 sub $0x18,%rsp
12: 48 89 04 24 mov %rax,(%rsp)
16: 48 89 e7 mov %rsp,%rdi
19: 48 b8 dd dd dd dd dd movabs $0xdddddddddddddddd,%rax
20: dd dd dd
23: 48 89 44 24 08 mov %rax,0x8(%rsp)
28: e8 00 00 00 00 call 2d <guid_direct+0x2d>
2d: 48 83 c4 18 add $0x18,%rsp
31: c3 ret
For guid_static(), gcc stores the GUID in .data and emits a RIP-relative
address load:
32: f3 0f 1e fa endbr64
36: 48 8d 3d 00 00 00 00 lea 0x0(%rip),%rdi
3d: e9 00 00 00 00 jmp 42 <guid_static+0x10>
Overall, guid_direct() consumes 50 bytes in the .text segment whereas
guid_static() needs only 32 bytes in total: 16 bytes in .data and 16
bytes in .text.
Move these direct GUID references to function-local static objects and
pass their address instead. EFI boot service prototypes take non-const
efi_guid_t pointers, so keep the GUID non-const to prevent a
-Wdiscarded-qualifiers warning.
For an x86_64 build with gcc 15.3.0, bloat-o-meter reports:
add/remove: 6/0 grow/shrink: 0/3 up/down: 112/-458 (-346)
Function old new delta
graphics_output_guid - 32 +32
smbios_guid - 16 +16
edid_discovered_guid - 16 +16
edid_active_guid - 16 +16
console_out_device_guid - 16 +16
apple_set_os_guid - 16 +16
efi_stub_entry 4180 4136 -44
efi_get_smbios_record 283 226 -57
efi_setup_graphics 2210 1853 -357
Total: Before=29223, After=28877, chg -1.18%
Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
---
drivers/firmware/efi/libstub/gop.c | 17 ++++++++++-------
drivers/firmware/efi/libstub/smbios.c | 3 ++-
drivers/firmware/efi/libstub/x86-stub.c | 3 ++-
drivers/firmware/efi/libstub/zboot.c | 3 ++-
4 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/drivers/firmware/efi/libstub/gop.c b/drivers/firmware/efi/libstub/gop.c
index 80dc8cfeb33e..acc2827ba4d7 100644
--- a/drivers/firmware/efi/libstub/gop.c
+++ b/drivers/firmware/efi/libstub/gop.c
@@ -425,6 +425,8 @@ static void setup_edid_info(struct edid_info *edid, u32 gop_size_of_edid, u8 *go
static efi_handle_t find_handle_with_primary_gop(unsigned long num, const efi_handle_t handles[],
efi_graphics_output_protocol_t **found_gop)
{
+ static efi_guid_t graphics_output_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+ static efi_guid_t console_out_device_guid = EFI_CONSOLE_OUT_DEVICE_GUID;
efi_graphics_output_protocol_t *first_gop;
efi_handle_t h, first_gop_handle;
@@ -439,8 +441,7 @@ static efi_handle_t find_handle_with_primary_gop(unsigned long num, const efi_ha
efi_graphics_output_mode_info_t *info;
void *dummy = NULL;
- status = efi_bs_call(handle_protocol, h,
- &EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID,
+ status = efi_bs_call(handle_protocol, h, &graphics_output_guid,
(void **)&gop);
if (status != EFI_SUCCESS)
continue;
@@ -462,7 +463,7 @@ static efi_handle_t find_handle_with_primary_gop(unsigned long num, const efi_ha
* don't bother looking any further.
*/
status = efi_bs_call(handle_protocol, h,
- &EFI_CONSOLE_OUT_DEVICE_GUID, &dummy);
+ &console_out_device_guid, &dummy);
if (status == EFI_SUCCESS) {
if (found_gop)
*found_gop = gop;
@@ -480,6 +481,9 @@ static efi_handle_t find_handle_with_primary_gop(unsigned long num, const efi_ha
efi_status_t efi_setup_graphics(struct screen_info *si, struct edid_info *edid)
{
+ static efi_guid_t graphics_output_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+ static efi_guid_t edid_active_guid = EFI_EDID_ACTIVE_PROTOCOL_GUID;
+ static efi_guid_t edid_discovered_guid = EFI_EDID_DISCOVERED_PROTOCOL_GUID;
efi_handle_t *handles __free(efi_pool) = NULL;
efi_handle_t handle;
efi_graphics_output_protocol_t *gop;
@@ -487,8 +491,7 @@ efi_status_t efi_setup_graphics(struct screen_info *si, struct edid_info *edid)
unsigned long num;
status = efi_bs_call(locate_handle_buffer, EFI_LOCATE_BY_PROTOCOL,
- &EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID, NULL, &num,
- &handles);
+ &graphics_output_guid, NULL, &num, &handles);
if (status != EFI_SUCCESS)
return status;
@@ -510,14 +513,14 @@ efi_status_t efi_setup_graphics(struct screen_info *si, struct edid_info *edid)
u32 gop_size_of_edid = 0;
u8 *gop_edid = NULL;
- status = efi_bs_call(handle_protocol, handle, &EFI_EDID_ACTIVE_PROTOCOL_GUID,
+ status = efi_bs_call(handle_protocol, handle, &edid_active_guid,
(void **)&active_edid);
if (status == EFI_SUCCESS) {
gop_size_of_edid = efi_table_attr(active_edid, size_of_edid);
gop_edid = efi_table_attr(active_edid, edid);
} else {
status = efi_bs_call(handle_protocol, handle,
- &EFI_EDID_DISCOVERED_PROTOCOL_GUID,
+ &edid_discovered_guid,
(void **)&discovered_edid);
if (status == EFI_SUCCESS) {
gop_size_of_edid = efi_table_attr(discovered_edid, size_of_edid);
diff --git a/drivers/firmware/efi/libstub/smbios.c b/drivers/firmware/efi/libstub/smbios.c
index f31410d7e7e1..efbbfc3c2c0d 100644
--- a/drivers/firmware/efi/libstub/smbios.c
+++ b/drivers/firmware/efi/libstub/smbios.c
@@ -35,12 +35,13 @@ union efi_smbios_protocol {
const struct efi_smbios_record *efi_get_smbios_record(u8 type)
{
+ static efi_guid_t smbios_guid = EFI_SMBIOS_PROTOCOL_GUID;
struct efi_smbios_record *record;
efi_smbios_protocol_t *smbios;
efi_status_t status;
u16 handle = 0xfffe;
- status = efi_bs_call(locate_protocol, &EFI_SMBIOS_PROTOCOL_GUID, NULL,
+ status = efi_bs_call(locate_protocol, &smbios_guid, NULL,
(void **)&smbios) ?:
efi_call_proto(smbios, get_next, &handle, &type, &record, NULL);
if (status != EFI_SUCCESS)
diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c
index cef32e2c82d8..cb0abe13a6c4 100644
--- a/drivers/firmware/efi/libstub/x86-stub.c
+++ b/drivers/firmware/efi/libstub/x86-stub.c
@@ -335,6 +335,7 @@ static bool apple_match_product_name(void)
static void apple_set_os(void)
{
+ static efi_guid_t apple_set_os_guid = APPLE_SET_OS_PROTOCOL_GUID;
struct {
unsigned long version;
efi_status_t (__efiapi *set_os_version)(const char *);
@@ -345,7 +346,7 @@ static void apple_set_os(void)
if (!efi_is_64bit() || !apple_match_product_name())
return;
- status = efi_bs_call(locate_protocol, &APPLE_SET_OS_PROTOCOL_GUID, NULL,
+ status = efi_bs_call(locate_protocol, &apple_set_os_guid, NULL,
(void **)&set_os);
if (status != EFI_SUCCESS)
return;
diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c
index 4b76f74c56da..4a5ffe164873 100644
--- a/drivers/firmware/efi/libstub/zboot.c
+++ b/drivers/firmware/efi/libstub/zboot.c
@@ -34,6 +34,7 @@ struct sysfb_display_info *alloc_primary_display(void)
asmlinkage efi_status_t __efiapi
efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
{
+ static efi_guid_t loaded_image_guid = LOADED_IMAGE_PROTOCOL_GUID;
char *cmdline_ptr __free(efi_pool) = NULL;
unsigned long image_base, alloc_size;
efi_loaded_image_t *image;
@@ -42,7 +43,7 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
WRITE_ONCE(efi_system_table, systab);
status = efi_bs_call(handle_protocol, handle,
- &LOADED_IMAGE_PROTOCOL_GUID, (void **)&image);
+ &loaded_image_guid, (void **)&image);
if (status != EFI_SUCCESS) {
efi_err("Failed to locate parent's loaded image protocol\n");
return status;
--
2.55.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 2/3] efi/libstub: make local GUID variables static
2026-09-03 21:25 [PATCH 0/3] efi/libstub: reduce size by optimizing GUID storage Vincent Mailhol
2026-09-03 21:25 ` [PATCH 1/3] efi/libstub: move direct GUID references to static storage Vincent Mailhol
@ 2026-09-03 21:25 ` Vincent Mailhol
2026-09-03 21:25 ` [PATCH 3/3] efi/libstub: factor shared static GUID variables Vincent Mailhol
2026-09-04 16:31 ` [PATCH 0/3] efi/libstub: reduce size by optimizing GUID storage Ard Biesheuvel
3 siblings, 0 replies; 5+ messages in thread
From: Vincent Mailhol @ 2026-09-03 21:25 UTC (permalink / raw)
To: Ard Biesheuvel, Ilias Apalodimas; +Cc: linux-efi, linux-kernel, Vincent Mailhol
Local efi_guid_t variables with automatic storage produce assembly
similar to passing the address of the GUID macro directly. For the same
reason, make these GUID variables static.
Put the static declarations first in their local declaration block to
visually separate them from the automatic variables.
For an x86_64 build with gcc 15.3.0, bloat-o-meter reports:
add/remove: 15/0 grow/shrink: 0/10 up/down: 336/-742 (-406)
Function old new delta
tbl_guid - 32 +32
rng_proto - 32 +32
pci_proto - 32 +32
guid - 32 +32
fs_proto - 32 +32
cc_guid - 32 +32
tpm2_guid - 16 +16
text_to_dp_guid - 16 +16
tcg2_guid - 16 +16
rng_table_guid - 16 +16
rng_algo_raw - 16 +16
proto - 16 +16
linux_eventlog_guid - 16 +16
lf2_proto_guid - 16 +16
info_guid - 16 +16
efi_get_memory_map 707 696 -11
efi_pci_disable_bridge_busmaster 1199 1184 -15
efi_get_random_bytes 216 188 -28
efi_remap_image 357 328 -29
efi_load_initrd 1113 1065 -48
efi_random_get_seed 1368 1297 -71
efi_measure_tagged_event 935 854 -81
efi_retrieve_eventlog 1686 1570 -116
handle_cmdline_files 2501 2341 -160
efi_stub_entry 4136 3953 -183
Total: Before=28877, After=28471, chg -1.41%
Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
---
drivers/firmware/efi/libstub/efi-stub-entry.c | 2 +-
drivers/firmware/efi/libstub/efi-stub-helper.c | 10 +++++-----
drivers/firmware/efi/libstub/efi-stub.c | 2 +-
drivers/firmware/efi/libstub/file.c | 8 ++++----
drivers/firmware/efi/libstub/kaslr.c | 2 +-
drivers/firmware/efi/libstub/mem.c | 2 +-
drivers/firmware/efi/libstub/pci.c | 2 +-
drivers/firmware/efi/libstub/random.c | 8 ++++----
drivers/firmware/efi/libstub/riscv.c | 2 +-
drivers/firmware/efi/libstub/tpm.c | 8 ++++----
drivers/firmware/efi/libstub/unaccepted_memory.c | 2 +-
drivers/firmware/efi/libstub/x86-stub.c | 10 +++++-----
12 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/drivers/firmware/efi/libstub/efi-stub-entry.c b/drivers/firmware/efi/libstub/efi-stub-entry.c
index aa85e910fe59..8ecd8cd72561 100644
--- a/drivers/firmware/efi/libstub/efi-stub-entry.c
+++ b/drivers/firmware/efi/libstub/efi-stub-entry.c
@@ -35,13 +35,13 @@ struct sysfb_display_info *alloc_primary_display(void)
efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
efi_system_table_t *systab)
{
+ static efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
efi_loaded_image_t *image;
efi_status_t status;
unsigned long image_addr;
unsigned long image_size = 0;
/* addr/point and size pairs for memory management*/
char *cmdline_ptr = NULL;
- efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
unsigned long reserve_addr = 0;
unsigned long reserve_size = 0;
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index f27f2e1f0019..48f93f7758e9 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -248,6 +248,7 @@ static efi_status_t efi_measure_tagged_event(unsigned long load_addr,
unsigned long load_size,
enum efistub_event_type event)
{
+ static efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID;
union {
efi_status_t
(__efiapi *hash_log_extend_event)(void *, u64, efi_physical_addr_t,
@@ -257,7 +258,6 @@ static efi_status_t efi_measure_tagged_event(unsigned long load_addr,
struct efistub_measured_event *evt __free(efi_pool) = NULL;
int size = struct_size(evt, tagged_event.tagged_event_data,
events[event].event_data_len);
- efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID;
efi_tcg2_protocol_t *tcg2 = NULL;
union efistub_event ev;
efi_status_t status;
@@ -276,7 +276,7 @@ static efi_status_t efi_measure_tagged_event(unsigned long load_addr,
method.hash_log_extend_event =
(void *)efi_table_attr(tcg2, hash_log_extend_event);
} else {
- efi_guid_t cc_guid = EFI_CC_MEASUREMENT_PROTOCOL_GUID;
+ static efi_guid_t cc_guid = EFI_CC_MEASUREMENT_PROTOCOL_GUID;
efi_cc_protocol_t *cc = NULL;
efi_bs_call(locate_protocol, &cc_guid, NULL, (void **)&cc);
@@ -552,7 +552,7 @@ static
efi_status_t efi_load_initrd_dev_path(struct linux_efi_initrd *initrd,
unsigned long max)
{
- efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
+ static efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
efi_device_path_protocol_t *dp;
efi_load_file2_protocol_t *lf2;
efi_handle_t handle;
@@ -614,7 +614,7 @@ efi_status_t efi_load_initrd(efi_loaded_image_t *image,
unsigned long hard_limit,
const struct linux_efi_initrd **out)
{
- efi_guid_t tbl_guid = LINUX_EFI_INITRD_MEDIA_GUID;
+ static efi_guid_t tbl_guid = LINUX_EFI_INITRD_MEDIA_GUID;
efi_status_t status = EFI_SUCCESS;
struct linux_efi_initrd initrd, *tbl;
@@ -725,7 +725,7 @@ efi_status_t efi_wait_for_key(unsigned long usec, efi_input_key_t *key)
void efi_remap_image(unsigned long image_base, unsigned alloc_size,
unsigned long code_size)
{
- efi_guid_t guid = EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;
+ static efi_guid_t guid = EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;
efi_memory_attribute_protocol_t *memattr;
efi_status_t status;
u64 attr;
diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c
index 42d6073bcd06..235c9738da2d 100644
--- a/drivers/firmware/efi/libstub/efi-stub.c
+++ b/drivers/firmware/efi/libstub/efi-stub.c
@@ -79,8 +79,8 @@ static struct sysfb_display_info *setup_primary_display(void)
static void install_memreserve_table(void)
{
+ static efi_guid_t memreserve_table_guid = LINUX_EFI_MEMRESERVE_TABLE_GUID;
struct linux_efi_memreserve *rsv;
- efi_guid_t memreserve_table_guid = LINUX_EFI_MEMRESERVE_TABLE_GUID;
efi_status_t status;
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, sizeof(*rsv),
diff --git a/drivers/firmware/efi/libstub/file.c b/drivers/firmware/efi/libstub/file.c
index bd626d55dcbc..0dff9e08d49e 100644
--- a/drivers/firmware/efi/libstub/file.c
+++ b/drivers/firmware/efi/libstub/file.c
@@ -39,7 +39,7 @@ static efi_status_t efi_open_file(efi_file_protocol_t *volume,
efi_file_protocol_t **handle,
unsigned long *file_size)
{
- efi_guid_t info_guid = EFI_FILE_INFO_ID;
+ static efi_guid_t info_guid = EFI_FILE_INFO_ID;
efi_file_protocol_t *fh;
unsigned long info_sz;
efi_status_t status;
@@ -74,7 +74,7 @@ static efi_status_t efi_open_file(efi_file_protocol_t *volume,
static efi_status_t efi_open_volume(efi_loaded_image_t *image,
efi_file_protocol_t **fh)
{
- efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
+ static efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
efi_simple_file_system_protocol_t *io;
efi_status_t status;
@@ -128,9 +128,9 @@ static int find_file_option(const efi_char16_t *cmdline, int cmdline_len,
static efi_status_t efi_open_device_path(efi_file_protocol_t **volume,
struct finfo *fi)
{
- efi_guid_t text_to_dp_guid = EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID;
+ static efi_guid_t text_to_dp_guid = EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID;
+ static efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
static efi_device_path_from_text_protocol_t *text_to_dp = NULL;
- efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
efi_device_path_protocol_t *initrd_dp;
efi_simple_file_system_protocol_t *io;
struct efi_file_path_dev_path *fpath;
diff --git a/drivers/firmware/efi/libstub/kaslr.c b/drivers/firmware/efi/libstub/kaslr.c
index 4bc963e999eb..f5074656457a 100644
--- a/drivers/firmware/efi/libstub/kaslr.c
+++ b/drivers/firmware/efi/libstub/kaslr.c
@@ -18,7 +18,7 @@
*/
u32 efi_kaslr_get_phys_seed(efi_handle_t image_handle)
{
- efi_guid_t li_fixed_proto = LINUX_EFI_LOADED_IMAGE_FIXED_GUID;
+ static efi_guid_t li_fixed_proto = LINUX_EFI_LOADED_IMAGE_FIXED_GUID;
void *p;
if (!IS_ENABLED(CONFIG_RANDOMIZE_BASE))
diff --git a/drivers/firmware/efi/libstub/mem.c b/drivers/firmware/efi/libstub/mem.c
index 59f3f83de50c..fec561e3a792 100644
--- a/drivers/firmware/efi/libstub/mem.c
+++ b/drivers/firmware/efi/libstub/mem.c
@@ -20,10 +20,10 @@
efi_status_t efi_get_memory_map(struct efi_boot_memmap **map,
bool install_cfg_tbl)
{
+ static efi_guid_t tbl_guid = LINUX_EFI_BOOT_MEMMAP_GUID;
struct efi_boot_memmap tmp, *m __free(efi_pool) = NULL;
int memtype = install_cfg_tbl ? EFI_ACPI_RECLAIM_MEMORY
: EFI_LOADER_DATA;
- efi_guid_t tbl_guid = LINUX_EFI_BOOT_MEMMAP_GUID;
efi_status_t status;
unsigned long size;
diff --git a/drivers/firmware/efi/libstub/pci.c b/drivers/firmware/efi/libstub/pci.c
index 1dccf77958d3..5daa7a0a0e87 100644
--- a/drivers/firmware/efi/libstub/pci.c
+++ b/drivers/firmware/efi/libstub/pci.c
@@ -15,7 +15,7 @@
void efi_pci_disable_bridge_busmaster(void)
{
- efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
+ static efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
efi_handle_t *pci_handle __free(efi_pool) = NULL;
unsigned long pci_handle_num;
efi_handle_t handle;
diff --git a/drivers/firmware/efi/libstub/random.c b/drivers/firmware/efi/libstub/random.c
index 7109b8a2dcba..3ca230fa7aa3 100644
--- a/drivers/firmware/efi/libstub/random.c
+++ b/drivers/firmware/efi/libstub/random.c
@@ -38,7 +38,7 @@ union efi_rng_protocol {
*/
efi_status_t efi_get_random_bytes(unsigned long size, u8 *out)
{
- efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
+ static efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
efi_status_t status;
efi_rng_protocol_t *rng = NULL;
@@ -64,9 +64,9 @@ efi_status_t efi_get_random_bytes(unsigned long size, u8 *out)
*/
efi_status_t efi_random_get_seed(void)
{
- efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
- efi_guid_t rng_algo_raw = EFI_RNG_ALGORITHM_RAW;
- efi_guid_t rng_table_guid = LINUX_EFI_RANDOM_SEED_TABLE_GUID;
+ static efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
+ static efi_guid_t rng_algo_raw = EFI_RNG_ALGORITHM_RAW;
+ static efi_guid_t rng_table_guid = LINUX_EFI_RANDOM_SEED_TABLE_GUID;
struct linux_efi_random_seed *prev_seed, *seed = NULL;
int prev_seed_size = 0, seed_size = EFI_RANDOM_SEED_SIZE;
unsigned long nv_seed_size = 0, offset = 0;
diff --git a/drivers/firmware/efi/libstub/riscv.c b/drivers/firmware/efi/libstub/riscv.c
index f66f33ceb99e..49db47c05bfe 100644
--- a/drivers/firmware/efi/libstub/riscv.c
+++ b/drivers/firmware/efi/libstub/riscv.c
@@ -45,7 +45,7 @@ static int get_boot_hartid_from_fdt(void)
static efi_status_t get_boot_hartid_from_efi(void)
{
- efi_guid_t boot_protocol_guid = RISCV_EFI_BOOT_PROTOCOL_GUID;
+ static efi_guid_t boot_protocol_guid = RISCV_EFI_BOOT_PROTOCOL_GUID;
struct riscv_efi_boot_protocol *boot_protocol;
efi_status_t status;
diff --git a/drivers/firmware/efi/libstub/tpm.c b/drivers/firmware/efi/libstub/tpm.c
index a5c6c4f163fc..73f001114732 100644
--- a/drivers/firmware/efi/libstub/tpm.c
+++ b/drivers/firmware/efi/libstub/tpm.c
@@ -28,8 +28,8 @@ static const efi_char16_t efi_MemoryOverWriteRequest_name[] =
*/
void efi_enable_reset_attack_mitigation(void)
{
+ static efi_guid_t var_guid = MEMORY_ONLY_RESET_CONTROL_GUID;
u8 val = 1;
- efi_guid_t var_guid = MEMORY_ONLY_RESET_CONTROL_GUID;
efi_status_t status;
unsigned long datasize = 0;
@@ -52,7 +52,7 @@ static void efi_retrieve_tcg2_eventlog(int version, efi_physical_addr_t log_loca
efi_bool_t truncated,
struct efi_tcg2_final_events_table *final_events_table)
{
- efi_guid_t linux_eventlog_guid = LINUX_EFI_TPM_EVENT_LOG_GUID;
+ static efi_guid_t linux_eventlog_guid = LINUX_EFI_TPM_EVENT_LOG_GUID;
efi_status_t status;
struct linux_efi_tpm_eventlog *log_tbl = NULL;
unsigned long first_entry_addr, last_entry_addr;
@@ -150,9 +150,9 @@ static void efi_retrieve_tcg2_eventlog(int version, efi_physical_addr_t log_loca
void efi_retrieve_eventlog(void)
{
+ static efi_guid_t tpm2_guid = EFI_TCG2_PROTOCOL_GUID;
struct efi_tcg2_final_events_table *final_events_table = NULL;
efi_physical_addr_t log_location = 0, log_last_entry = 0;
- efi_guid_t tpm2_guid = EFI_TCG2_PROTOCOL_GUID;
int version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
efi_tcg2_protocol_t *tpm2 = NULL;
efi_bool_t truncated;
@@ -173,7 +173,7 @@ void efi_retrieve_eventlog(void)
get_efi_config_table(EFI_TCG2_FINAL_EVENTS_TABLE_GUID);
}
} else {
- efi_guid_t cc_guid = EFI_CC_MEASUREMENT_PROTOCOL_GUID;
+ static efi_guid_t cc_guid = EFI_CC_MEASUREMENT_PROTOCOL_GUID;
efi_cc_protocol_t *cc = NULL;
status = efi_bs_call(locate_protocol, &cc_guid, NULL, (void **)&cc);
diff --git a/drivers/firmware/efi/libstub/unaccepted_memory.c b/drivers/firmware/efi/libstub/unaccepted_memory.c
index 757dbe734a47..2a7eac7fef86 100644
--- a/drivers/firmware/efi/libstub/unaccepted_memory.c
+++ b/drivers/firmware/efi/libstub/unaccepted_memory.c
@@ -9,7 +9,7 @@ struct efi_unaccepted_memory *unaccepted_table;
efi_status_t allocate_unaccepted_bitmap(__u32 nr_desc,
struct efi_boot_memmap *map)
{
- efi_guid_t unaccepted_table_guid = LINUX_EFI_UNACCEPTED_MEM_TABLE_GUID;
+ static efi_guid_t unaccepted_table_guid = LINUX_EFI_UNACCEPTED_MEM_TABLE_GUID;
u64 unaccepted_start = ULLONG_MAX, unaccepted_end = 0, bitmap_size;
efi_status_t status;
int i;
diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c
index cb0abe13a6c4..0bae0f06b676 100644
--- a/drivers/firmware/efi/libstub/x86-stub.c
+++ b/drivers/firmware/efi/libstub/x86-stub.c
@@ -114,9 +114,9 @@ preserve_pci_rom_image(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom)
*/
static void setup_efi_pci(struct boot_params *params)
{
+ static efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
efi_status_t status;
efi_handle_t *pci_handle __free(efi_pool) = NULL;
- efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
struct setup_data *data;
unsigned long num;
efi_handle_t h;
@@ -155,7 +155,7 @@ static void setup_efi_pci(struct boot_params *params)
static void retrieve_apple_device_properties(struct boot_params *boot_params)
{
- efi_guid_t guid = APPLE_PROPERTIES_PROTOCOL_GUID;
+ static efi_guid_t guid = APPLE_PROPERTIES_PROTOCOL_GUID;
struct setup_data *data, *new;
efi_status_t status;
u32 size = 0;
@@ -445,7 +445,7 @@ efi_status_t efi_adjust_memory_range_protection(unsigned long start,
static void setup_unaccepted_memory(void)
{
- efi_guid_t mem_acceptance_proto = OVMF_SEV_MEMORY_ACCEPTANCE_PROTOCOL_GUID;
+ static efi_guid_t mem_acceptance_proto = OVMF_SEV_MEMORY_ACCEPTANCE_PROTOCOL_GUID;
sev_memory_acceptance_protocol_t *proto;
efi_status_t status;
@@ -508,7 +508,7 @@ static void __noreturn efi_exit(efi_handle_t handle, efi_status_t status)
static efi_status_t efi_allocate_bootparams(efi_handle_t handle,
struct boot_params **bp)
{
- efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
+ static efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
struct boot_params *boot_params;
struct setup_header *hdr;
efi_status_t status;
@@ -915,7 +915,7 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
struct boot_params *boot_params)
{
- efi_guid_t guid = EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;
+ static efi_guid_t guid = EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;
const struct linux_efi_initrd *initrd = NULL;
unsigned long kernel_entry;
struct setup_header *hdr;
--
2.55.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 3/3] efi/libstub: factor shared static GUID variables
2026-09-03 21:25 [PATCH 0/3] efi/libstub: reduce size by optimizing GUID storage Vincent Mailhol
2026-09-03 21:25 ` [PATCH 1/3] efi/libstub: move direct GUID references to static storage Vincent Mailhol
2026-09-03 21:25 ` [PATCH 2/3] efi/libstub: make local GUID variables static Vincent Mailhol
@ 2026-09-03 21:25 ` Vincent Mailhol
2026-09-04 16:31 ` [PATCH 0/3] efi/libstub: reduce size by optimizing GUID storage Ard Biesheuvel
3 siblings, 0 replies; 5+ messages in thread
From: Vincent Mailhol @ 2026-09-03 21:25 UTC (permalink / raw)
To: Ard Biesheuvel, Ilias Apalodimas; +Cc: linux-efi, linux-kernel, Vincent Mailhol
Some GUIDs are used several times in the same translation unit.
Factor the duplicated EFI_FILE_SYSTEM_GUID, EFI_RNG_PROTOCOL_GUID and
EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID objects at file scope within their
translation units. Leave the single-use GUID objects at function scope.
For an x86_64 build with gcc 15.3.0, bloat-o-meter reports:
add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-48 (-48)
Function old new delta
rng_proto 32 16 -16
graphics_output_guid 32 16 -16
fs_proto 32 16 -16
Total: Before=28471, After=28423, chg -0.17%
Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
---
drivers/firmware/efi/libstub/file.c | 4 ++--
drivers/firmware/efi/libstub/gop.c | 4 ++--
drivers/firmware/efi/libstub/random.c | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/firmware/efi/libstub/file.c b/drivers/firmware/efi/libstub/file.c
index 0dff9e08d49e..b2601e284695 100644
--- a/drivers/firmware/efi/libstub/file.c
+++ b/drivers/firmware/efi/libstub/file.c
@@ -29,6 +29,8 @@
*/
#define EFI_READ_CHUNK_SIZE SZ_1M
+static efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
+
struct finfo {
efi_file_info_t info;
efi_char16_t filename[MAX_FILENAME_SIZE];
@@ -74,7 +76,6 @@ static efi_status_t efi_open_file(efi_file_protocol_t *volume,
static efi_status_t efi_open_volume(efi_loaded_image_t *image,
efi_file_protocol_t **fh)
{
- static efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
efi_simple_file_system_protocol_t *io;
efi_status_t status;
@@ -129,7 +130,6 @@ static efi_status_t efi_open_device_path(efi_file_protocol_t **volume,
struct finfo *fi)
{
static efi_guid_t text_to_dp_guid = EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID;
- static efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
static efi_device_path_from_text_protocol_t *text_to_dp = NULL;
efi_device_path_protocol_t *initrd_dp;
efi_simple_file_system_protocol_t *io;
diff --git a/drivers/firmware/efi/libstub/gop.c b/drivers/firmware/efi/libstub/gop.c
index acc2827ba4d7..fa324d4abcaa 100644
--- a/drivers/firmware/efi/libstub/gop.c
+++ b/drivers/firmware/efi/libstub/gop.c
@@ -24,6 +24,8 @@ enum efi_cmdline_option {
EFI_CMDLINE_LIST
};
+static efi_guid_t graphics_output_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+
static struct {
enum efi_cmdline_option option;
union {
@@ -425,7 +427,6 @@ static void setup_edid_info(struct edid_info *edid, u32 gop_size_of_edid, u8 *go
static efi_handle_t find_handle_with_primary_gop(unsigned long num, const efi_handle_t handles[],
efi_graphics_output_protocol_t **found_gop)
{
- static efi_guid_t graphics_output_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
static efi_guid_t console_out_device_guid = EFI_CONSOLE_OUT_DEVICE_GUID;
efi_graphics_output_protocol_t *first_gop;
efi_handle_t h, first_gop_handle;
@@ -481,7 +482,6 @@ static efi_handle_t find_handle_with_primary_gop(unsigned long num, const efi_ha
efi_status_t efi_setup_graphics(struct screen_info *si, struct edid_info *edid)
{
- static efi_guid_t graphics_output_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
static efi_guid_t edid_active_guid = EFI_EDID_ACTIVE_PROTOCOL_GUID;
static efi_guid_t edid_discovered_guid = EFI_EDID_DISCOVERED_PROTOCOL_GUID;
efi_handle_t *handles __free(efi_pool) = NULL;
diff --git a/drivers/firmware/efi/libstub/random.c b/drivers/firmware/efi/libstub/random.c
index 3ca230fa7aa3..d63262d36e47 100644
--- a/drivers/firmware/efi/libstub/random.c
+++ b/drivers/firmware/efi/libstub/random.c
@@ -8,6 +8,8 @@
#include "efistub.h"
+static efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
+
typedef union efi_rng_protocol efi_rng_protocol_t;
union efi_rng_protocol {
@@ -38,7 +40,6 @@ union efi_rng_protocol {
*/
efi_status_t efi_get_random_bytes(unsigned long size, u8 *out)
{
- static efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
efi_status_t status;
efi_rng_protocol_t *rng = NULL;
@@ -64,7 +65,6 @@ efi_status_t efi_get_random_bytes(unsigned long size, u8 *out)
*/
efi_status_t efi_random_get_seed(void)
{
- static efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
static efi_guid_t rng_algo_raw = EFI_RNG_ALGORITHM_RAW;
static efi_guid_t rng_table_guid = LINUX_EFI_RANDOM_SEED_TABLE_GUID;
struct linux_efi_random_seed *prev_seed, *seed = NULL;
--
2.55.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH 0/3] efi/libstub: reduce size by optimizing GUID storage
2026-09-03 21:25 [PATCH 0/3] efi/libstub: reduce size by optimizing GUID storage Vincent Mailhol
` (2 preceding siblings ...)
2026-09-03 21:25 ` [PATCH 3/3] efi/libstub: factor shared static GUID variables Vincent Mailhol
@ 2026-09-04 16:31 ` Ard Biesheuvel
3 siblings, 0 replies; 5+ messages in thread
From: Ard Biesheuvel @ 2026-09-04 16:31 UTC (permalink / raw)
To: Vincent Mailhol, Ilias Apalodimas; +Cc: linux-efi, linux-kernel
On Thu, 3 Sep 2026, at 23:25, Vincent Mailhol wrote:
> The EFI stub is size-sensitive. Several call sites currently pass GUID
> macro addresses directly, or keep GUID objects as automatic local
> variables. With gcc, this materializes the GUID at the call site,
> resulting in several assembly instructions. Using static storage instead
> emits 16 bytes of GUID data and only one instruction to pass its
> address.
>
> The first two patches convert direct GUID references and automatic GUID
> variables to static storage. The last patch factors GUID objects that
> are shared within the same translation unit.
>
> For the full series, on an x86_64 build with gcc 15.3.0, bloat-o-meter
> reports:
>
> add/remove: 21/0 grow/shrink: 0/12 up/down: 400/-1200 (-800)
> Function old new delta
> tbl_guid - 32 +32
> pci_proto - 32 +32
> guid - 32 +32
> cc_guid - 32 +32
> tpm2_guid - 16 +16
> text_to_dp_guid - 16 +16
> tcg2_guid - 16 +16
> smbios_guid - 16 +16
> rng_table_guid - 16 +16
> rng_proto - 16 +16
> rng_algo_raw - 16 +16
> proto - 16 +16
> linux_eventlog_guid - 16 +16
> lf2_proto_guid - 16 +16
> info_guid - 16 +16
> graphics_output_guid - 16 +16
> fs_proto - 16 +16
> edid_discovered_guid - 16 +16
> edid_active_guid - 16 +16
> console_out_device_guid - 16 +16
> apple_set_os_guid - 16 +16
> efi_get_memory_map 707 696 -11
> efi_pci_disable_bridge_busmaster 1199 1184 -15
> efi_get_random_bytes 216 188 -28
> efi_remap_image 357 328 -29
> efi_load_initrd 1113 1065 -48
> efi_get_smbios_record 283 226 -57
> efi_random_get_seed 1368 1297 -71
> efi_measure_tagged_event 935 854 -81
> efi_retrieve_eventlog 1686 1570 -116
> handle_cmdline_files 2501 2341 -160
> efi_stub_entry 4180 3953 -227
> efi_setup_graphics 2210 1853 -357
> Total: Before=29223, After=28423, chg -2.74%
>
> See this as my penitence for adding the BLI feature: I am giving you
> back the bytes that I consumed, and even more.
>
Thanks :-)
It would be nice if we could rely on SHF_MERGE sections here, but that
doesn't seem tractable in the context of the stub.
> Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
> ---
> Vincent Mailhol (3):
> efi/libstub: move direct GUID references to static storage
> efi/libstub: make local GUID variables static
> efi/libstub: factor shared static GUID variables
>
Applied to efi/next
^ permalink raw reply [flat|nested] 5+ messages in thread