From 38ea3bfc6506174c3ae219b33171db2c2098afd1 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Wed, 11 Feb 2026 16:56:20 +0100 Subject: efi_var_file: refactor to move buffer functions Currently efi_var_file.c has functions to store/read EFI variables to/from memory buffer. These functions can be used with other EFI variable stores so move them out to efi_var_common.c Signed-off-by: Shantur Rathore Signed-off-by: Michal Simek Tested-by: Neil Armstrong # on AML-S905D3-CC Reviewed-by: Ilias Apalodimas Reviewed-by: Heinrich Schuchardt --- include/efi_variable.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/efi_variable.h') diff --git a/include/efi_variable.h b/include/efi_variable.h index 4065cf45eca..ee68fa4a885 100644 --- a/include/efi_variable.h +++ b/include/efi_variable.h @@ -161,6 +161,11 @@ efi_status_t efi_var_to_file(void); efi_status_t __maybe_unused efi_var_collect(struct efi_var_file **bufp, loff_t *lenp, u32 check_attr_mask); +/* GUID used by Shim to store the MOK database */ +#define SHIM_LOCK_GUID \ + EFI_GUID(0x605dab50, 0xe046, 0x4300, \ + 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) + /** * efi_var_restore() - restore EFI variables from buffer * -- cgit v1.2.3 From 4fcc248c943b10889789f23b372ce37e06614a84 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 11 Feb 2026 16:56:21 +0100 Subject: efi_var: Unify read/write access helper function efi_var_to/from_file() suggest method where variables are placed. But there is no reason for it and generic name can be used to wire also different locations for variables. Signed-off-by: Michal Simek Reviewed-by: Ilias Apalodimas Tested-by: Neil Armstrong # on AML-S905D3-CC Reviewed-by: Heinrich Schuchardt --- include/efi_variable.h | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'include/efi_variable.h') diff --git a/include/efi_variable.h b/include/efi_variable.h index ee68fa4a885..fc1184e5ca1 100644 --- a/include/efi_variable.h +++ b/include/efi_variable.h @@ -137,13 +137,11 @@ struct efi_var_file { }; /** - * efi_var_to_file() - save non-volatile variables as file - * - * File ubootefi.var is created on the EFI system partion. + * efi_var_to_storage() - save non-volatile variables * * Return: status code */ -efi_status_t efi_var_to_file(void); +efi_status_t efi_var_to_storage(void); /** * efi_var_collect() - collect variables in buffer @@ -178,17 +176,14 @@ efi_status_t __maybe_unused efi_var_collect(struct efi_var_file **bufp, loff_t * efi_status_t efi_var_restore(struct efi_var_file *buf, bool safe); /** - * efi_var_from_file() - read variables from file - * - * File ubootefi.var is read from the EFI system partitions and the variables - * stored in the file are created. + * efi_var_from_storage() - read variables * * In case the file does not exist yet or a variable cannot be set EFI_SUCCESS * is returned. * * Return: status code */ -efi_status_t efi_var_from_file(void); +efi_status_t efi_var_from_storage(void); /** * efi_var_mem_init() - set-up variable list -- cgit v1.2.3 From 94c5c0835bccdb0763c25af7fdf72cdd2b9f7e5a Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 13 Mar 2026 12:20:37 +0100 Subject: 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 Reviewed-by: Heinrich Schuchardt Signed-off-by: Michal Simek Reviewed-by: Ilias Apalodimas --- include/efi_variable.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include/efi_variable.h') diff --git a/include/efi_variable.h b/include/efi_variable.h index fc1184e5ca1..c3229c717d8 100644 --- a/include/efi_variable.h +++ b/include/efi_variable.h @@ -216,6 +216,11 @@ void efi_var_mem_del(struct efi_var_entry *var); * The variable is appended without checking if a variable of the same name * already exists. The two data buffers are concatenated. * + * When @changep is non-NULL and @size2 is 0, the function compares the new + * value against an existing variable with the same name and vendor. If + * attributes and data are identical the insertion is skipped and *@changep + * is set to false, avoiding superfluous writes. + * * @variable_name: variable name * @vendor: GUID * @attributes: variable attributes @@ -224,13 +229,14 @@ void efi_var_mem_del(struct efi_var_entry *var); * @size2: size of the second data field * @data2: second data buffer * @time: time of authentication (as seconds since start of epoch) + * @changep: pointer to change flag (may be NULL) * Result: status code */ efi_status_t efi_var_mem_ins(const u16 *variable_name, const efi_guid_t *vendor, u32 attributes, const efi_uintn_t size1, const void *data1, const efi_uintn_t size2, const void *data2, - const u64 time); + const u64 time, bool *changep); /** * efi_var_mem_free() - determine free memory for variables -- cgit v1.2.3