[PATCH 07/12] efi: selftest: add runtime variable tests with non-volatile storage
Harsimran Singh Tungal
harsimransingh.tungal at arm.com
Fri Apr 24 19:31:46 CEST 2026
Extend runtime variable tests for persistent storage
Previously, EFI selftesting of runtime variables was only supported
under CONFIG_EFI_RT_VOLATILE_STORE, which uses VarToFile to simulate
non-volatile variable storage. This commit adds new test cases that
exercise runtime variable operations for persistent storage.
Features tested:
- Creation of runtime-accessible variables (set)
- Retrieval of runtime variables (get)
- Deletion using SetVariable() with size = 0
- Append operation using EFI_VARIABLE_APPEND_WRITE
This improves EFI compliance validation for non-volatile runtime storage
scenarios and ensures proper attribute enforcement and variable
management.
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal at arm.com>
---
.../efi_selftest_variables_runtime.c | 106 +++++++++++++++++-
1 file changed, 104 insertions(+), 2 deletions(-)
diff --git a/lib/efi_selftest/efi_selftest_variables_runtime.c b/lib/efi_selftest/efi_selftest_variables_runtime.c
index fd570d673f0..9a7ab18bc90 100644
--- a/lib/efi_selftest/efi_selftest_variables_runtime.c
+++ b/lib/efi_selftest/efi_selftest_variables_runtime.c
@@ -3,6 +3,7 @@
* efi_selftest_variables_runtime
*
* Copyright (c) 2019 Heinrich Schuchardt <xypron.glpk at gmx.de>
+ * Copyright (c) 2026 Arm Limited and/or its affiliates <open-source-office at arm.com>
*
* This unit test checks the runtime services for variables after
* ExitBootServices():
@@ -22,7 +23,13 @@ static const efi_guid_t efi_rt_var_guid = U_BOOT_EFI_RT_VAR_FILE_GUID;
/**
* execute() - execute unit test
*
- * As runtime support is not implmented expect EFI_UNSUPPORTED to be returned.
+ * For EFI variables in non-volatile storage, these tests have to be executed in two phases
+ * 1. During first phase, run these tests and it creates EFI variable in persistent storage.
+ * 2. Then reboot and run the test again to verify if the variable created above is still
+ * available in non-volatile storage. If available, validate the EFI variable, append
+ * it, and validate it again. If validation is successful, delete the same variable.
+ *
+ * Return: EFI_ST_SUCCESS on success, EFI_ST_FAILURE on failure
*/
static int execute(void)
{
@@ -39,6 +46,80 @@ static int execute(void)
u64 max_storage, rem_storage, max_size;
int test_ret;
+ /* Compare the value of EFI variable if it already exists in non volatile storage */
+ if (!IS_ENABLED(CONFIG_EFI_RT_VOLATILE_STORE)) {
+ len = sizeof(v) / 2;
+ ret = st_runtime->get_variable(u"efi_st_var0", &guid_vendor0,
+ &attr, &len, data);
+ if (ret == EFI_SUCCESS) {
+ efi_st_printf("EFI Variable efi_st_var0 found. Executing Second Phase\n");
+ if (len != sizeof(v) / 2) {
+ efi_st_error("GetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+ if (memcmp(data, v, len)) {
+ efi_st_error("GetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /* Append an existing variable */
+ append_len = sizeof(v) - len;
+ ret = st_runtime->set_variable(u"efi_st_var0", &guid_vendor0,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_APPEND_WRITE |
+ EFI_VARIABLE_NON_VOLATILE,
+ append_len, (v + len));
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("SetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ len = sizeof(v);
+ ret = st_runtime->get_variable(u"efi_st_var0", &guid_vendor0,
+ &attr, &len, data);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("GetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ if (len != sizeof(v)) {
+ efi_st_error("GetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ if (memcmp(data, v, len)) {
+ efi_st_error("GetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /* Delete it by setting the size to 0 */
+ ret = st_runtime->set_variable(u"efi_st_var0", &guid_vendor0,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_NON_VOLATILE,
+ 0, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("SetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ ret = st_runtime->get_variable(u"efi_st_var0", &guid_vendor0,
+ &attr, &len, data);
+ if (ret != EFI_NOT_FOUND) {
+ efi_st_error("GetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ return EFI_ST_SUCCESS;
+ } else {
+ if (ret == EFI_NOT_FOUND) {
+ efi_st_printf("EFI Variable efi_st_var0 not found. "
+ "Executing First Phase\n");
+ }
+ }
+ }
+
memset(v2, 0x1, sizeof(v2));
if (IS_ENABLED(CONFIG_EFI_VARIABLE_FILE_STORE)) {
@@ -279,7 +360,28 @@ static int execute(void)
return EFI_ST_FAILURE;
}
} else {
- if (ret != EFI_UNSUPPORTED) {
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("SetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /* Delete it by setting the size to 0 */
+ ret = st_runtime->set_variable(u"efi_st_var0", &guid_vendor0,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ 0, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("SetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /* Add an 8byte aligned variable */
+ ret = st_runtime->set_variable(u"efi_st_var0", &guid_vendor0,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_NON_VOLATILE,
+ sizeof(v) / 2, v);
+ if (ret != EFI_SUCCESS) {
efi_st_error("SetVariable failed\n");
return EFI_ST_FAILURE;
}
--
2.34.1
More information about the U-Boot
mailing list