diff --git a/source/chapter2-uefi.rst b/source/chapter2-uefi.rst index 243b198..a7cd618 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 ----------------------- @@ -610,17 +621,21 @@ 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 ----------------------- +.. 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. @@ -628,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()`, diff --git a/source/chapter5-variable-storage.rst b/source/chapter5-variable-storage.rst index fb80a7c..6a8271d 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.