1Context Management Library 2************************** 3 4This document provides an overview of the Context Management library implementation 5in Trusted Firmware-A (TF-A). It enumerates and describes the APIs implemented 6and their accessibility from other components at EL3. 7 8Overview 9======== 10 11Arm TrustZone architecture facilitates hardware-enforced isolation between 12software running in various security states (Secure/Non-Secure/Realm). 13The general-purpose registers, most of the system registers and vector registers 14are not banked per world. When moving between the security states it is the 15responsibility of the secure monitor software (BL31(AArch64) / BL32(Aarch32)) 16in TF-A, not the hardware, to save and restore register state. 17Refer to `Trustzone for AArch64`_ for more details. 18 19EL3 Runtime Firmware, also termed as secure monitor firmware, is integrated 20with a context management library to handle the context of the CPU, managing the 21saving and restoring of register states across the worlds. 22 23TF-A Context 24============ 25 26In TF-A, the context is represented as a data structure used by the EL3 firmware 27to preserve the state of the CPU at the next lower exception level (EL) in a given 28security state and save enough EL3 metadata to be able to return to that exception 29level and security state. The memory for the context data structures are allocated 30in BSS section of EL3 firmware. 31 32In a trusted system at any instance, a given CPU could be executing in one of the 33security states (Non-Secure, Secure, Realm). Each world must have its 34configuration of system registers independent of other security states to access 35and execute any of the architectural features. 36 37If the CPU switches across security states (for example: from Non-secure to Secure 38or vice versa), the register contents, especially the ones that are not banked 39(EL2/EL1, vector, general-purpose registers), will be overwritten, as the software 40running in either state has the privileges to access them. Additionally, some of 41the architectural features enabled in the former security state will be unconditionally 42accessible in the latter security state as well. This can be a major concern when 43dealing with security-specific bits, as they need to be explicitly enabled or 44disabled in each state to prevent data leakage across the worlds. 45 46In general, an ideal trusted system should have Secure world-specific configurations 47that are not influenced by Normal World operations. Therefore, for each CPU, we 48need to maintain world-specific context to ensure that register entries from one 49world do not leak or impact the execution of the CPU in other worlds. 50This will help ensure the integrity and security of the system, preventing any 51unauthorized access or data corruption between the different security states. 52 53Design 54====== 55 56The Context Management library in TF-A is designed to cover all the requirements 57for maintaining world-specific context essential for a trusted system. 58This includes implementing CPU context initialization and management routines, 59as well as other helper APIs that are required by dispatcher components in EL3 60firmware, which are collectively referred to as CPU Context Management. 61The APIs and their usecases are listed in detail under the :ref:`Library APIs` 62section. 63 64Originally, the Context Management library in TF-A was designed to cater for a 65two-world system, comprising of Non-Secure and Secure Worlds. In this case, the 66EL3 Firmware is assumed to be running in Secure World. 67With introduction of Realm Management Extension (RME), from Armv9.2 a system 68can have four distinct worlds (Non-Secure, Secure, Realm, Root). 69RME isolates EL3 from all other Security states and moves it into its own security 70state called root. EL3 firmware now runs at Root World and thereby is 71trusted from software in Non-secure, Secure, and Realm states. 72Refer to `Security States with RME`_ for more details. 73 74Key principles followed in designing the context management library : 75 761. **EL3 should only initialize immediate used lower EL** 77 78Context Management library running at EL3 should only initialize and monitor the 79immediate used lower EL. This implies that, when S-EL2 is present in the system, 80EL3 should initialise and monitor S-EL2 registers only. S-EL1 registers should 81not be the concern of EL3 while S-EL2 is in place. In systems where S-EL2 is 82absent, S-EL1 registers should be initialised from EL3. 83 842. **Decentralized model for context management** 85 86Each world (Non-Secure, Secure, and Realm) should have their separate component 87in EL3 responsible for their respective world context management. 88Both the Secure and Realm world have associated dispatcher components in EL3 89firmware to allow management of the respective worlds. For the Non-Secure world, 90PSCI Library (BL31)/context management library provides routines to help 91initialize the Non-Secure world context. 92 933. **Flexibility for Dispatchers to select desired feature set to save and restore** 94 95Each feature is supported with a helper function ``is_feature_supported(void)``, 96to detect its presence at runtime. This helps dispatchers to select the desired 97feature set, and thereby save and restore the configuration associated with them. 98 994. **Dynamic discovery of Feature enablement by EL3** 100 101TF-A supports four states for feature enablement at EL3, to make them available 102for lower exception levels. 103 104.. code:: c 105 106 #define FEAT_STATE_DISABLED 0 107 #define FEAT_STATE_ENABLED 1 108 #define FEAT_STATE_CHECK 2 109 110A pattern is established for feature enablement behavior. 111Each feature must support the 3 possible values with rigid semantics. 112 113- **FEAT_STATE_DISABLED** - all code relating to this feature is always skipped. 114 Firmware is unaware of this feature. 115 116- **FEAT_STATE_ALWAYS** - all code relating to this feature is always executed. 117 Firmware expects this feature to be present in hardware. 118 119- **FEAT_STATE_CHECK** - same as ``FEAT_STATE_ALWAYS`` except that the feature's 120 existence will be checked at runtime. Default on dynamic platforms (example: FVP). 121 122 .. note:: 123 124 In general, it is assumed that all cores will support the same set of 125 architectural features (features will be symmetrical). However, there are 126 cases where this is impractical to achieve. Only some features can be 127 mismatched among cores and this is the exception rather than the rule. This 128 is due to the fact that Operating systems are designed for SMP systems. There 129 are no clear guidelines what kind of mismatch is allowed but following 130 pointers can help in making a decision: 131 132 - All mandatory features must be symmetric. 133 - Any feature that impacts the generation of page tables must be symmetric. 134 - Any feature access which does not trap to EL3 should be symmetric. 135 - Features related with profiling, debug and trace could be asymmetric 136 - Migration of vCPU/tasks between CPUs should not cause an error 137 138 TF-A caters for mismatched features, however, this is not regularly tested 139 for all features and may not work as expected, even without considering OS 140 support. 141 142 .. note:: 143 ``FEAT_RAS`` is an exception here, as it impacts the execution of EL3 and 144 it is essential to know its presence at compile time. Refer to ``ENABLE_FEAT`` 145 macro under :ref:`Build Options` section for more details. 146 147Code Structure 148============== 149 150`lib/el3_runtime/(aarch32/aarch64)`_ - Context library code directory. 151 152Source Files 153~~~~~~~~~~~~ 154 155#. ``context_mgmt.c`` : consists of core functions that setup, save and restore 156 context for different security states alongside high level feature enablement 157 APIs for individual worlds. 158 159#. ``cpu_data_array.c`` : contains per_cpu_data structure instantiation. 160 161#. ``context.S`` : consists of functions that save and restore some of the context 162 structure members in assembly code. 163 164#. ``cpu_data.S`` : consists of helper functions to initialise per_cpu_data pointers. 165 166#. ``el3_common_macros.S`` : consists of macros to facilitate actions to be performed 167 during cold and warmboot and el3 registers initialisation in assembly code. 168 169Header Files 170~~~~~~~~~~~~ 171 172#. ``context_mgmt.h`` : contains the public interface to Context Management Library. 173 174#. ``context.h`` : contains the helper macros and definitions for context entries. 175 176#. ``cpu_data.h`` : contains the public interface to Per CPU data structure. 177 178#. ``context_debug.h`` : contains public interface to report context memory 179 utilisation across the security states. 180 181#. ``context_el2.h`` : internal header consisting of helper macros to access EL2 182 context entries. Used by ``context.h``. 183 184Apart from these files, we have some context related source files under ``BL1`` 185and ``BL31`` directory. ``bl1_context_mgmt.c`` ``bl31_context_mgmt.c`` 186 187Bootloader Images utilizing Context Management Library 188====================================================== 189 190+-------------------------------------------+-----------------------------+ 191| Bootloader | Context Management Library | 192+-------------------------------------------+-----------------------------+ 193| BL1 | Yes | 194+-------------------------------------------+-----------------------------+ 195| BL2 | No | 196+-------------------------------------------+-----------------------------+ 197| BL31 (Aarch64- EL3runtime firmware) | Yes | 198+-------------------------------------------+-----------------------------+ 199| BL32 (Aarch32- EL3runtime firmware) | Yes | 200+-------------------------------------------+-----------------------------+ 201 202CPU Data Structure 203================== 204For a given system, depending on the CPU count, the platform statically 205allocates memory for the CPU data structure. 206 207.. code:: c 208 209 /* The per_cpu_ptr_cache_t space allocation */ 210 cpu_data_t percpu_data[PLATFORM_CORE_COUNT]; 211 212This CPU data structure has a member element with an array of pointers to hold 213the Non-Secure, Realm and Secure security state context structures as listed below. 214 215.. code:: c 216 217 typedef struct cpu_data { 218 #ifdef __aarch64__ 219 void *cpu_context[CPU_DATA_CONTEXT_NUM]; 220 #endif 221 222 .... 223 .... 224 225 #if (ENABLE_FEAT_IDTE3 && defined(__aarch64__)) 226 percpu_idregs_t idregs[CPU_CONTEXT_NUM]; 227 #endif 228 }cpu_data_t; 229 230|CPU Data Structure| 231 232At runtime, ``cpu_context[CPU_DATA_CONTEXT_NUM]`` array will be intitialised with 233the Secure, Non-Secure and Realm context structure addresses to ensure proper 234handling of the register state. 235See :ref:`Library APIs` section for more details. 236 237When FEAT_IDTE3 is enabled, the ID registers ID_AA64DFR0_EL1 and 238ID_AA64DFR1_EL1 are cached in the 239percpu_idregs_t idregs[CPU_CONTEXT_NUM] array within the CPU data 240structure. These cached copies are used to service trapped reads of the 241corresponding registers from lower exception levels. Because debug and 242trace features can vary across CPUs, these ID registers are cached 243per-CPU and per-world to accurately represent asymmetric 244configurations. 245 246The per-cpu cached ID registers are initialized in ``psci_arch_setup()`` 247via ``cm_init_percpu_once_regs()``. 248 249CPU Context and Memory allocation 250================================= 251 252CPU Context 253~~~~~~~~~~~ 254The members of the context structure used by the EL3 firmware to preserve the 255state of CPU across exception levels for a given security state are listed below. 256 257.. code:: c 258 259 typedef struct cpu_context { 260 gp_regs_t gpregs_ctx; 261 el3_state_t el3state_ctx; 262 263 cve_2018_3639_t cve_2018_3639_ctx; 264 265 #if ERRATA_SPECULATIVE_AT 266 errata_speculative_at_t errata_speculative_at_ctx; 267 #endif 268 269 #if CTX_INCLUDE_PAUTH_REGS 270 pauth_t pauth_ctx; 271 #endif 272 273 #if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) 274 el2_sysregs_t el2_sysregs_ctx; 275 #else 276 el1_sysregs_t el1_sysregs_ctx; 277 #endif 278 } cpu_context_t; 279 280Context Memory Allocation 281~~~~~~~~~~~~~~~~~~~~~~~~~ 282 283CPUs maintain their context per world. The individual context memory allocation 284for each CPU per world is allocated by the world-specific dispatcher components 285at compile time as shown below. 286 287|Context memory allocation| 288 289NS-Context Memory 290~~~~~~~~~~~~~~~~~ 291It's important to note that the Normal world doesn't possess the dispatcher 292component found in the Secure and Realm worlds. Instead, the PSCI library at EL3 293handles memory allocation for ``Non-Secure`` world context for all CPUs. 294 295.. code:: c 296 297 static PER_CPU_DEFINE(cpu_context_t, psci_ns_context); 298 299Secure-Context Memory 300~~~~~~~~~~~~~~~~~~~~~ 301Secure World dispatcher (such as SPMD) at EL3 allocates the memory for ``Secure`` 302world context of all CPUs. 303 304.. code:: c 305 306 static PER_CPU_DEFINE(spmd_spm_core_context_t, spm_core_context); 307 308Realm-Context Memory 309~~~~~~~~~~~~~~~~~~~~ 310Realm World dispatcher (RMMD) at EL3 allocates the memory for ``Realm`` world 311context of all CPUs. 312 313.. code:: c 314 315 PER_CPU_DEFINE(rmmd_rmm_context_t, rmm_context); 316 317To summarize, the world-specific context structures are synchronized with 318per-CPU data structures, which means that each CPU will have an array of pointers 319to individual worlds. The figure below illustrates the same. 320 321|CPU Context Memory Configuration| 322 323Context Setup/Initialization 324============================ 325 326The CPU has been assigned context structures for every security state, which include 327Non-Secure, Secure and Realm. It is crucial to initialize each of these structures 328during the bootup of every CPU before they enter any security state for the 329first time. This section explains the specifics of how the initialization of 330every CPU context takes place during both cold and warm boot paths. 331 332Context Setup during Cold boot 333~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 334The cold boot path is mainly executed by the primary CPU, other than essential 335CPU initialization executed by all CPUs. After executing BL1 and BL2, the Primary 336CPU jumps to the BL31 image for runtime services initialization. 337During this process, the per_cpu_data structure gets initialized with statically 338allocated world-specific context memory. 339 340Later in the cold boot sequence, the BL31 image at EL3 checks for the presence 341of a Secure world image at S-EL2. If detected, it invokes the secure context 342initialization sequence under SPMD. Additionally, based on RME enablement, 343the Realm context gets initialized from the RMMD at EL3. Finally, before exiting 344to the normal world, the Non-Secure context gets initialized via the context 345management library. At this stage, all Primary CPU contexts are initialized 346and the CPU exits EL3 to enter the Normal world. 347 348|Context Init ColdBoot| 349 350.. note:: 351 The figure above illustrates a scenario on FVP for one of the build 352 configurations with TFTF component at NS-EL2. 353 354Context Setup during Warmboot 355~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 356 357During a warm boot sequence, the primary CPU is responsible for powering on the 358secondary CPUs. Refer to :ref:`CPU Reset` and :ref:`Firmware Design` sections for 359more details on the warm boot. 360 361|Context Init WarmBoot| 362 363The primary CPU writes the entrypoint for the secondary CPU. When the secondary 364wakes up it initialises its own context via ``cm_init_my_context( ep )`` using 365the provided entrypoint. 366 367``psci_warmboot_entrypoint()`` is the warm boot entrypoint procedure. 368During the warm bootup process, secondary CPUs have their secure context 369initialized through SPMD at EL3. Upon successful SP initialization, the SPD 370power management operations become shared with the PSCI library. During this 371process, the SPMD duly registers its handlers with the PSCI library. 372 373.. code:: c 374 375 file: psci_common.c 376 const spd_pm_ops_t *psci_spd_pm; 377 378 file: spmd_pm.c 379 const spd_pm_ops_t spmd_pm = { 380 .svc_on_finish = spmd_cpu_on_finish_handler, 381 .svc_off = spmd_cpu_off_handler 382 } 383 384Secondary CPUs during their bootup in the ``psci_cpu_on_finish()`` routine get 385their secure context initialised via the registered SPMD handler 386``spmd_cpu_on_finish_handler()`` at EL3. 387The figure above illustrates the same with reference of Primary CPU running at 388NS-EL2. 389 390.. _Library APIs: 391 392Library APIs 393============ 394 395The public APIs and types can be found in ``include/lib/el3_runtime/context_management.h`` 396and this section is intended to provide additional details and clarifications. 397 398Context Initialization for Individual Worlds 399~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 400The library implements high level APIs for the CPUs in setting up their individual 401context for each world (Non-Secure, Secure and Realm). 402 403.. c:function:: static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *ep); 404 405This function is responsible for the general context initialization that applies 406to all worlds. It will be invoked first, before calling the individual 407world-specific context setup APIs. 408 409.. c:function:: static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *ep); 410.. c:function:: static void setup_realm_context(cpu_context_t *ctx, const struct entry_point_info *ep); 411.. c:function:: static void setup_secure_context(cpu_context_t *ctx, const struct entry_point_info *ep); 412 413Depending on the security state that the CPU needs to enter, the respective 414world-specific context setup handlers listed above will be invoked once per-CPU 415to set up the context for their execution. 416 417.. c:function:: void cm_manage_extensions_el3(void) 418 419This function initializes all EL3 registers whose values do not change during the 420lifetime of EL3 runtime firmware. It is invoked from each CPU via the cold boot 421path ``bl31_main()`` and in the WarmBoot entry path ``void psci_warmboot_entrypoint()``. 422 423Runtime Save and Restore of Registers 424~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 425 426EL1 Registers 427------------- 428 429.. c:function:: void cm_el1_sysregs_context_save(uint32_t security_state); 430.. c:function:: void cm_el1_sysregs_context_restore(uint32_t security_state); 431 432These functions are utilized by the world-specific dispatcher components running 433at EL3 to facilitate the saving and restoration of the EL1 system registers 434during a world switch. 435 436EL2 Registers 437------------- 438 439.. c:function:: void cm_el2_sysregs_context_save(uint32_t security_state); 440.. c:function:: void cm_el2_sysregs_context_restore(uint32_t security_state); 441 442These functions are utilized by the world-specific dispatcher components running 443at EL3 to facilitate the saving and restoration of the EL2 system registers 444during a world switch. 445 446Pauth Registers 447--------------- 448 449Pointer Authentication feature is enabled by default for Non-Secure world and 450disabled for Secure and Realm worlds. In this case, we don't need to explicitly 451save and restore the Pauth registers during world switch. 452However, ``CTX_INCLUDE_PAUTH_REGS`` flag is explicitly used to enable Pauth for 453lower exception levels of Secure and Realm worlds. In this scenario, we save the 454general purpose and Pauth registers while we enter EL3 from lower ELs via 455``prepare_el3_entry`` and restore them back while we exit EL3 to lower ELs 456via ``el3_exit``. 457 458.. code:: c 459 460 .macro save_gp_pmcr_pauth_regs 461 func restore_gp_pmcr_pauth_regs 462 463Feature Enablement for Individual Worlds 464~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 465 466.. c:function:: static void manage_extensions_nonsecure(cpu_context_t *ctx); 467.. c:function:: static void manage_extensions_secure(cpu_context_t *ctx); 468.. c:function:: static void manage_extensions_realm(cpu_context_t *ctx) 469 470Functions that allow the enabling and disabling of architectural features for 471each security state. These functions are invoked from the top-level setup APIs 472during context initialization. 473 474Further, a pattern is established for feature enablement code (AArch64). 475Each feature implements following APIs as applicable: 476Note: (``xxx`` is the name of the feature in the APIs) 477 478- ``is_feat_xxx_supported()`` and ``is_feat_xxx_present()`` - mandatory for all features. 479 480- ``xxx_enable(cpu_context * )`` and ``xxx_disable(cpu_context * )`` - optional 481 functions to enable the feature for the passed context only. To be called in 482 the respective world's setup_context to select behaviour. 483 484- ``xxx_init_el3()`` - optional function to enable the feature in-place in any EL3 485 registers that are never context switched. The values they write must never 486 change, otherwise the functions mentioned in previous point should be used. 487 Invoked from ``cm_manage_extensions_el3()``. 488 489- ``xxx_init_el2_unused()`` - optional function to enable the feature in-place 490 in any EL2 registers that are necessary for execution in EL1 with no EL2 present. 491 492The above mentioned rules, followed for ``FEAT_SME`` is shown below: 493 494.. code:: c 495 496 void sme_enable(cpu_context_t *context); 497 void sme_init_el3(void); 498 void sme_init_el2_unused(void); 499 void sme_disable(cpu_context_t *context); 500 501Per-world Context 502================= 503 504Apart from the CPU context structure, we have another structure to manage some 505of the EL3 system registers whose values are identical across all the CPUs 506referred to as ``per_world_context_t``. 507The Per-world context structure is intended for managing EL3 system registers with 508identical values across all CPUs, requiring only a singular context entry for each 509individual world. This structure operates independently of the CPU context 510structure and is intended to manage specific EL3 registers. 511 512.. code-block:: c 513 514 typedef struct per_world_context { 515 uint64_t ctx_cptr_el3; 516 uint64_t ctx_mpam3_el3; 517 #if (ENABLE_FEAT_IDTE3 && IMAGE_BL31) 518 perworld_idregs_t idregs; 519 #endif 520 } per_world_context_t; 521 522When FEAT_IDTE3 (Trapping ID register accesses to EL3) is enabled, 523the ``per_world_context_t`` structure includes a ``perworld_idregs_t`` member 524that caches architectural ID registers common across all CPUs in a world. 525This cache allows EL3 firmware to provide consistent, virtualized ID register 526values to lower exception levels when traps occur. The cached values stored in 527``idregs`` are returned in place of the actual hardware register values. 528During initialization, the per-world ID register cache is populated by 529``idte3_init_cached_idregs_per_world()``. 530 531These functions facilitate the activation of architectural extensions that possess 532identical values across all cores for the individual Non-secure, Secure, and 533Realm worlds. 534 535Root-Context (EL3-Execution-Context) 536==================================== 537 538EL3/Root Context is the execution environment while the CPU is running at EL3. 539 540Previously, while the CPU is in execution at EL3, the system registers persist 541with the values of the incoming world. This implies that if the CPU is entering 542EL3 from NS world, the EL1 and EL2 system registers which might be modified in 543lower exception levels NS(EL2/EL1) will carry forward those values to EL3. 544Further the EL3 registers also hold on to the values configured for Non-secure 545world, written during the previous ERET from EL3 to NS(EL2/EL1). 546Same policy is followed with respect to other worlds (Secure/Realm) depending on 547the system configuration. 548 549The firmware at EL3 has traditionally operated within the context of the incoming 550world (Secure/Non-Secure/Realm). This becomes problematic in scenarios where the 551EL3/Root world must explicitly use architectural features that depend on system 552registers configured for lower exception levels. 553A good example of this is the PAuth regs. The Root world would need to program 554its own PAuth Keys while executing in EL3 and this needs to be restored in entry 555to EL3 from any world. 556Therefore, Root world should maintain its own distinct settings to access 557features for its own execution at EL3. 558 559Register values which are currently known to be of importance during EL3 execution, 560is referred to as the EL3/Root context. 561This includes ( MDCR_EL3.SDD, SCR_EL3.{EA, SIF}, PMCR_EL0.DP, PSTATE.DIT) 562EL3 Context ensures, CPU executes under fixed EL3 system register settings 563which is not affected by settings of other worlds. 564 565Root Context needs to be setup as early as possible before we try and access/modify 566architectural features at EL3. Its a simple restore operation ``setup_el3_execution_context`` 567that overwrites the selected bits listed above. EL3 never changes its mind about 568what those values should be, sets it as required for EL3. Henceforth, a Root 569context save operation is not required. 570 571The figure below illustrates the same with NS-world as a reference while entering 572EL3. 573 574|Root Context Sequence| 575 576.. code:: c 577 578 # EL3/Root_Context routine 579 .macro setup_el3_execution_context 580 581EL3 execution context needs to setup at both boot time (cold and warm boot) 582entrypaths and at all the possible exception handlers routing to EL3 at runtime. 583 584*Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.* 585 586.. |Context Memory Allocation| image:: ../resources/diagrams/context_memory_allocation.png 587.. |CPU Context Memory Configuration| image:: ../resources/diagrams/cpu_data_config_context_memory.png 588.. |CPU Data Structure| image:: ../resources/diagrams/percpu-data-struct.png 589.. |Context Init ColdBoot| image:: ../resources/diagrams/context_init_coldboot.png 590.. |Context Init WarmBoot| image:: ../resources/diagrams/context_init_warmboot.png 591.. |Root Context Sequence| image:: ../resources/diagrams/root_context_sequence.png 592.. _Trustzone for AArch64: https://developer.arm.com/documentation/102418/0101/TrustZone-in-the-processor/Switching-between-Security-states 593.. _Security States with RME: https://developer.arm.com/documentation/den0126/0100/Security-states 594.. _lib/el3_runtime/(aarch32/aarch64): https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/lib/el3_runtime 595