From 2e0dc1044cc04e960ae41229f3e992013a61a0c0 Mon Sep 17 00:00:00 2001 From: Ricardo Salveti Date: Sat, 18 Jul 2026 01:33:54 +0000 Subject: [PATCH 1/2] chapter5: specify runtime access to file-backed variable stores Firmware that stores EFI variables in a file cannot write that file once the OS controls the storage device. U-Boot keeps servicing the variable runtime services from a memory-backed store and delegates persisting it to the OS: the RTStorageVolatile variable names the store file on the ESP and VarToFile exports the content the file must have. The mechanism is also implemented by EDK2-based vendor firmware and supported by libefivar (rhboot/efivar#282), but it is only documented in U-Boot. Specify the mechanism so that firmware and operating systems can implement it from EBBR alone: define the vendor GUID, the semantics of the two variables, the firmware requirements including the runtime SetVariable() restrictions, and the write-back duties of the OS. While at it, retitle the chapter, whose scope now goes beyond the store file format, extend the limitations section accordingly, and add the chapter 2 anchor the new section refers to. Suggested-by: Ilias Apalodimas Signed-off-by: Ricardo Salveti --- source/chapter2-uefi.rst | 2 + source/chapter5-variable-storage.rst | 149 +++++++++++++++++++++++++-- 2 files changed, 144 insertions(+), 7 deletions(-) diff --git a/source/chapter2-uefi.rst b/source/chapter2-uefi.rst index 243b1980..1057dcdb 100644 --- a/source/chapter2-uefi.rst +++ b/source/chapter2-uefi.rst @@ -610,6 +610,8 @@ On AArch64 platforms, if `ResetSystem()` is not implemented then the Operating System should fall back to making a [PSCI]_ call to reset or shutdown the system. +.. _section-runtime-variable-access: + Runtime Variable Access ----------------------- diff --git a/source/chapter5-variable-storage.rst b/source/chapter5-variable-storage.rst index fb80a7c9..6a8271df 100644 --- a/source/chapter5-variable-storage.rst +++ b/source/chapter5-variable-storage.rst @@ -1,8 +1,8 @@ .. SPDX-License-Identifier: CC-BY-SA-4.0 -************************************* -File Format For Storing EFI Variables -************************************* +******************** +EFI Variable Storage +******************** .. versionadded:: 2.2.0 @@ -10,13 +10,18 @@ Some UEFI enabled devices can only store EFI variables as a file on a block device. This implies that at runtime the operating system must manage changes to the EFI variables by updating the file. -This chapter defines a file-format for EFI variables that both the firmware -and the operating system can rely on. +This chapter defines a file format for EFI variables that both the firmware +and the operating system can rely on, as well as a mechanism allowing the +operating system to persist variable modifications made with `SetVariable()` +during runtime services on behalf of the firmware. + +File Format For Storing EFI Variables +===================================== All integer fields are stored in little-endian byte order. File header -=========== +----------- The following byte sequence is used to identify the file format: @@ -70,7 +75,7 @@ Variables not sorted. Variable entries -================ +---------------- Each variable is stored as a structure: @@ -105,6 +110,128 @@ Data vendor’s variable followed by `DataSize` bytes of actual content of the variable. +.. _section-runtime-var-handover: + +Runtime Access to File-Backed Variables +======================================= + +.. versionadded:: 2.5.0 + +Firmware that stores EFI variables in a file usually cannot write to that +file after `ExitBootServices()`: the file resides on a storage device that is +controlled by the operating system at runtime, and any firmware access would +conflict with transactions initiated by the OS. + +This section defines a mechanism through which such firmware keeps the +variable runtime services available after `ExitBootServices()` by servicing +them from memory, and delegates writing the variable store file to the +operating system. See section :ref:`section-runtime-variable-access` for when +implementing this mechanism is required. + +Handover variables +------------------ + +Firmware implementing this mechanism shall provide the two variables +described below under the following vendor GUID: [#GuidNote]_ + +.. code-block:: c + + #define EBBR_RT_VAR_FILE_GUID \ + { 0xb2ac5fc9, 0x92b7, 0x4acd, \ + { 0xae, 0xac, 0x11, 0xe8, 0x18, 0xc3, 0x13, 0x0c }} + +.. [#GuidNote] The GUID value is fixed by existing implementations of this + mechanism. U-Boot defines it as `U_BOOT_EFI_RT_VAR_FILE_GUID`, and the + libefivar library detects the mechanism by looking up `RTStorageVolatile` + under this GUID. + +Both variables shall have the `EFI_VARIABLE_BOOTSERVICE_ACCESS` and +`EFI_VARIABLE_RUNTIME_ACCESS` attributes, shall not have the +`EFI_VARIABLE_NON_VOLATILE` attribute, and shall be read-only: any call to +`SetVariable()` targeting them shall fail with `EFI_WRITE_PROTECTED`. + +RTStorageVolatile + This variable contains the name of the variable store file as a NUL + terminated ASCII string. The file is located in the root directory of the + EFI System Partition holding the variable store, and the value shall not + contain any directory separator. E.g., U-Boot stores its EFI variables in + the file `ubootefi.var`. + +VarToFile + This variable contains the complete content that the variable store file + must have in order to persist the current state of all EFI variables + carrying the `EFI_VARIABLE_NON_VOLATILE` attribute. Firmware shall + regenerate the content every time the variable is read, so that it + reflects all preceding `SetVariable()` calls, including calls made during + runtime services. + + The operating system shall treat the content as an opaque binary blob. + Firmware using the file format defined in this chapter returns an + `EFI_VARIABLE_FILE` image holding all variables that have the + `EFI_VARIABLE_NON_VOLATILE` attribute set. [#FormatNote]_ + +.. [#FormatNote] The mechanism does not depend on the store file format, + as the operating system never interprets the store file content. + Firmware is nevertheless encouraged to use the file format defined in + this chapter. + +Firmware requirements +--------------------- + +Firmware implementing this mechanism shall: + +- Maintain a copy of the variable store in `EfiRuntimeServicesData` memory, + and service `GetVariable()` and `GetNextVariableName()` from that copy + during runtime services. + +- Implement `SetVariable()` during runtime services by applying the + modification to the in-memory store, without accessing the variable store + file. Modifications are consequently volatile until the operating system + writes them back to the store file, including modifications to variables + that have the `EFI_VARIABLE_NON_VOLATILE` attribute. + +- Advertise `EFI_RT_SUPPORTED_GET_VARIABLE`, + `EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME` and + `EFI_RT_SUPPORTED_SET_VARIABLE` in the `EFI_RT_PROPERTIES_TABLE` described + in :UEFI:`4.6.2`. + +The in-memory store imposes restrictions during runtime services. The +following operations shall fail: + +- Creating, modifying, or deleting authenticated variables (see + `Limitations`_ below). + +- Creating, modifying, or deleting volatile variables. + +- Modifying or deleting variables that do not have the + `EFI_VARIABLE_RUNTIME_ACCESS` attribute. These variables shall also be + hidden from `GetVariable()` and `GetNextVariableName()`. + +- Changing the attributes of an existing variable. + +Operating system requirements +----------------------------- + +To make a variable modification performed during runtime services +persistent, the operating system shall: + +1. Read the `RTStorageVolatile` variable to obtain the name of the variable + store file, and locate that file in the root directory of the EFI System + Partition. + +2. Read the `VarToFile` variable after the modification. + +3. Write the content of `VarToFile` to the variable store file. + +Modifications that have not been written back to the variable store file, +including modifications to variables that have the +`EFI_VARIABLE_NON_VOLATILE` attribute, are lost when the system resets. + +The operating system should update the variable store file atomically, so +that an interrupted update cannot corrupt the store. The variable store file +is created by the firmware; the operating system should only update an +existing file, and should not create the file when it is absent. + Limitations =========== @@ -119,3 +246,11 @@ signing certificates of nonce-based authenticated variables. [#CertNote]_ .. [#CertNote] Tianocore EDK II keeps signer certificates of authenticated variables in variables `certdb` and `certdbv`. + +Variables modified through the mechanism described in +:ref:`section-runtime-var-handover` only persist across reset if the +operating system writes the updated store content back to the variable store +file. Additionally, on systems with multiple EFI System Partitions, +`RTStorageVolatile` names the variable store file but not the partition +holding it, so identifying the correct partition is left to the operating +system. From 0e9abfd151a43ffdf111d7c6b43ef358a4b89533 Mon Sep 17 00:00:00 2001 From: Ricardo Salveti Date: Sat, 18 Jul 2026 01:33:54 +0000 Subject: [PATCH 2/2] chapter2: require variable runtime services for file-backed stores The Runtime Variable Access section only describes the option of not implementing SetVariable() after ExitBootServices() and claims that neither U-Boot nor Tianocore have a generic solution for variable stores on shared media, which is no longer accurate. Require firmware that stores EFI variables in a file on storage shared with the OS to implement the mechanism now specified in chapter 5, keeping GetVariable(), GetNextVariableName() and SetVariable() available during runtime services, and reflect this conditional requirement in the runtime services table. Platforms without a file-backed store keep the existing EFI_UNSUPPORTED / RuntimeServicesSupported fallback. Fixes: #143 Signed-off-by: Ricardo Salveti --- source/chapter2-uefi.rst | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/source/chapter2-uefi.rst b/source/chapter2-uefi.rst index 1057dcdb..a7cd6188 100644 --- a/source/chapter2-uefi.rst +++ b/source/chapter2-uefi.rst @@ -510,6 +510,8 @@ Functions that are not available during runtime services shall return :numref:`uefi_runtime_service_requirements` details which `EFI_RUNTIME_SERVICES` are required to be implemented during boot services and runtime services. +.. versionchanged:: 2.5.0 + .. _uefi_runtime_service_requirements: .. list-table:: `EFI_RUNTIME_SERVICES` Implementation Requirements :widths: 40 30 30 @@ -538,13 +540,16 @@ are required to be implemented during boot services and runtime services. - Required * - `GetVariable` - Required - - Optional + - Required for file-backed variable stores. [#RTVarNote]_ + Otherwise optional. * - `GetNextVariableName` - Required - - Optional + - Required for file-backed variable stores. [#RTVarNote]_ + Otherwise optional. * - `SetVariable` - Required - - Optional + - Required for file-backed variable stores. [#RTVarNote]_ + Otherwise optional. * - `GetNextHighMonotonicCount` - N/A - Optional @@ -561,6 +566,12 @@ are required to be implemented during boot services and runtime services. - Optional - Optional +.. [#RTVarNote] Firmware storing EFI variables in a file on storage shared + with the OS shall keep the variable services available during runtime + services by implementing the mechanism described in + :ref:`section-runtime-var-handover`. + See section :ref:`section-runtime-variable-access`. + Runtime Device Mappings ----------------------- @@ -615,14 +626,16 @@ system. Runtime Variable Access ----------------------- +.. versionchanged:: 2.5.0 + There are many platforms where it is difficult to implement `SetVariable()` for non-volatile variables during runtime services because the firmware cannot access storage after `ExitBootServices()` is called. e.g., If firmware accesses an eMMC device directly at runtime, it will collide with transactions initiated by the OS. -Neither U-Boot nor Tianocore have a generic solution for accessing or updating -variables stored on shared media. [#OPTEESupplicant]_ +Firmware cannot, on its own, safely update a variable store located on +storage media shared with the OS. [#OPTEESupplicant]_ .. [#OPTEESupplicant] It is worth noting that OP-TEE has a similar problem regarding secure storage. @@ -630,11 +643,20 @@ variables stored on shared media. [#OPTEESupplicant]_ storage operations on behalf of OP-TEE. The same solution may be applicable to solving the UEFI non-volatile variable problem, but it requires additional OS support to work. - Regardless, EBBR compliance does not require `SetVariable()` support - during runtime services. + Regardless, outside of the file-backed variable store case described + below, EBBR compliance does not require `SetVariable()` support during + runtime services. https://optee.readthedocs.io/en/4.9.0/architecture/secure_storage.html +If firmware stores EFI variables in a file on a storage device shared with +the operating system, then it shall implement the mechanism described in +:ref:`section-runtime-var-handover`, which keeps `GetVariable()`, +`GetNextVariableName()` and `SetVariable()` available during runtime +services: variable modifications are applied to an in-memory copy of the +variable store, and the operating system writes the updated store content +back to the variable store file. + If a platform does not implement modifying non-volatile variables with `SetVariable()` after `ExitBootServices()`, then firmware shall return `EFI_UNSUPPORTED` for any call to `SetVariable()`,