diff options
| author | Michal Simek <[email protected]> | 2026-03-13 12:20:37 +0100 |
|---|---|---|
| committer | Heinrich Schuchardt <[email protected]> | 2026-03-14 08:14:20 +0100 |
| commit | 94c5c0835bccdb0763c25af7fdf72cdd2b9f7e5a (patch) | |
| tree | ae8bc9a07158b520291cc76dd5b536f15b5127ef /lib/efi_loader/efi_runtime.c | |
| parent | a9080e600c214bbff331f95136aa26e7cfbe3375 (diff) | |
efi_loader: avoid superfluous variable store writes on unchanged data
Every SetVariable() call triggers efi_var_mem_ins() followed by
efi_var_to_storage(), even when the variable value is not actually
changing. This is unfriendly to flash-backed stores that suffer
wear from unnecessary erase/write cycles.
Add a change-detection path to efi_var_mem_ins(): when size2 == 0
(i.e. not an append) and the caller passes a non-NULL changep flag,
look up the existing variable and compare attributes, length, time
and data byte-by-byte. If everything matches, set *changep = false
and return EFI_SUCCESS without touching the variable buffer.
Both efi_set_variable_int() and efi_set_variable_runtime() now
check the flag and skip efi_var_mem_del() / efi_var_to_storage()
when nothing changed.
Introduce efi_memcmp_runtime() - a runtime-safe byte-by-byte memory
comparison helper, following the same pattern as the existing
efi_memcpy_runtime(). The standard memcmp() is not available after
ExitBootServices() and calling it from Linux will crash.
Tested-by: Heinrich Schuchardt <[email protected]>
Reviewed-by: Heinrich Schuchardt <[email protected]>
Signed-off-by: Michal Simek <[email protected]>
Reviewed-by: Ilias Apalodimas <[email protected]>
Diffstat (limited to 'lib/efi_loader/efi_runtime.c')
| -rw-r--r-- | lib/efi_loader/efi_runtime.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c index 35eb6a77766..73d4097464c 100644 --- a/lib/efi_loader/efi_runtime.c +++ b/lib/efi_loader/efi_runtime.c @@ -210,6 +210,30 @@ void __efi_runtime efi_memcpy_runtime(void *dest, const void *src, size_t n) } /** + * efi_memcmp_runtime() - compare memory areas + * + * At runtime memcmp() is not available. + * + * @s1: first memory area + * @s2: second memory area + * @n: number of bytes to compare + * Return: 0 if equal, negative if s1 < s2, positive if s1 > s2 + */ +int __efi_runtime efi_memcmp_runtime(const void *s1, const void *s2, size_t n) +{ + const u8 *pos1 = s1; + const u8 *pos2 = s2; + + for (; n; --n) { + if (*pos1 != *pos2) + return *pos1 - *pos2; + ++pos1; + ++pos2; + } + return 0; +} + +/** * efi_update_table_header_crc32() - Update crc32 in table header * * @table: EFI table |
