1# SMM based flash storage driver 2 3This documents the API exposed by the x86 system management based 4storage driver. 5 6## SMMSTORE 7 8SMMSTORE is a [SMM] mediated driver to read from, write to and erase a 9predefined region in flash. It can be enabled by setting 10`CONFIG_SMMSTORE=y` in menuconfig. 11 12This can be used by the OS or the payload to implement persistent 13storage to hold for instance configuration data, without needing 14to implement a (platform specific) storage driver in the payload 15itself. 16 17The API provides append-only semantics for key/value pairs. 18 19## API 20 21### Storage region 22 23By default SMMSTORE will operate on a separate FMAP region called 24`SMMSTORE`. The default generated FMAP will include such a region. 25On systems with a locked FMAP, e.g. in an existing vboot setup 26with a locked RO region, the option exists to add a cbfsfile 27called `smm_store` in the `RW_LEGACY` (if CHROMEOS) or in the 28`COREBOOT` FMAP regions. It is recommended for new builds using 29a handcrafted FMD that intend to make use of SMMSTORE to include a 30sufficiently large `SMMSTORE` FMAP region. It is recommended to 31align the `SMMSTORE` region to 64KiB for the largest flash erase 32op compatibility. 33 34When a default generated FMAP is used the size of the FMAP region 35is equal to `CONFIG_SMMSTORE_SIZE`. UEFI payloads expect at least 3664KiB. Given that the current implementation lacks a way to rewrite 37key-value pairs at least a multiple of this is recommended. 38 39### generating the SMI 40 41SMMSTORE is called via an SMI, which is generated via a write to the 42IO port defined in the smi_cmd entry of the FADT ACPI table. `%al` 43contains `APM_CNT_SMMSTORE=0xed` and is written to the smi_cmd IO 44port. `%ah` contains the SMMSTORE command. `%ebx` contains the 45parameter buffer to the SMMSTORE command. 46 47### Return values 48 49If a command succeeds, SMMSTORE will return with 50`SMMSTORE_RET_SUCCESS=0` on `%eax`. On failure SMMSTORE will return 51`SMMSTORE_RET_FAILURE=1`. For unsupported SMMSTORE commands 52`SMMSTORE_REG_UNSUPPORTED=2` is returned. 53 54**NOTE1**: The caller **must** check the return value and should make 55no assumption on the returned data if `%eax` does not contain 56`SMMSTORE_RET_SUCCESS`. 57 58**NOTE2**: If the SMI returns without changing `%ax` assume that the 59SMMSTORE feature is not installed. 60 61### Calling arguments 62 63SMMSTORE supports 3 subcommands that are passed via `%ah`, the additional 64calling arguments are passed via `%ebx`. 65 66**NOTE**: The size of the struct entries are in the native word size of 67smihandler. This means 32 bits in almost all cases. 68 69 70#### - SMMSTORE_CMD_CLEAR = 1 71 72This clears the `SMMSTORE` storage region. The argument in `%ebx` is 73unused. 74 75#### - SMMSTORE_CMD_READ = 2 76 77The additional parameter buffer `%ebx` contains a pointer to 78the following struct: 79 80```C 81struct smmstore_params_read { 82 void *buf; 83 ssize_t bufsize; 84}; 85``` 86 87INPUT: 88- `buf`: is a pointer to where the data needs to be read 89- `bufsize`: is the size of the buffer 90 91OUTPUT: 92- `buf` 93- `bufsize`: returns the amount of data that has actually been read. 94 95#### - SMMSTORE_CMD_APPEND = 3 96 97SMMSTORE takes a key-value approach to appending data. key-value pairs 98are never updated, they are always appended. It is up to the caller to 99walk through the key-value pairs after reading SMMSTORE to find the 100latest one. 101 102The additional parameter buffer `%ebx` contains a pointer to 103the following struct: 104 105```C 106struct smmstore_params_append { 107 void *key; 108 size_t keysize; 109 void *val; 110 size_t valsize; 111}; 112``` 113 114INPUT: 115- `key`: pointer to the key data 116- `keysize`: size of the key data 117- `val`: pointer to the value data 118- `valsize`: size of the value data 119 120#### Security 121 122Pointers provided by the payload or OS are checked to not overlap with the SMM. 123That protects the SMM handler from being manipulated. 124 125*However there's no validation done on the source or destination pointing to 126DRAM. A malicious application that is able to issue SMIs could extract arbitrary 127data or modify the currently running kernel.* 128 129## External links 130 131```{toctree} 132:maxdepth: 1 133 134A Tour Beyond BIOS Implementing UEFI Authenticated Variables in SMM with EDKI <https://software.intel.com/sites/default/files/managed/cf/ea/a_tour_beyond_bios_implementing_uefi_authenticated_variables_in_smm_with_edkii.pdf> 135``` 136Note, this differs significantly from coreboot's implementation. 137 138[SMM]: ../security/smm.md 139