blob: 56ba2ec1fec459feb6837bc701ab7608ea5e9803 [file] [log] [blame]
Jayanth Dodderi Chidanand346777f2023-10-30 17:34:48 +00001Context 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 three 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 ``FEAT_RAS`` is an exception here, as it impacts the execution of EL3 and
124 it is essential to know its presence at compile time. Refer to ``ENABLE_FEAT``
125 macro under :ref:`Build Options` section for more details.
126
127Code Structure
128==============
129
130`lib/el3_runtime/(aarch32/aarch64)`_ - Context library code directory.
131
132Source Files
133~~~~~~~~~~~~
134
135#. ``context_mgmt.c`` : consists of core functions that setup, save and restore
136 context for different security states alongside high level feature enablement
137 APIs for individual worlds.
138
139#. ``cpu_data_array.c`` : contains per_cpu_data structure instantiation.
140
141#. ``context.S`` : consists of functions that save and restore some of the context
142 structure members in assembly code.
143
144#. ``cpu_data.S`` : consists of helper functions to initialise per_cpu_data pointers.
145
146#. ``el3_common_macros.S`` : consists of macros to facilitate actions to be performed
147 during cold and warmboot and el3 registers initialisation in assembly code.
148
149Header Files
150~~~~~~~~~~~~
151
152#. ``context_mgmt.h`` : contains the public interface to Context Management Library.
153
154#. ``context.h`` : contains the helper macros and definitions for context entries.
155
156#. ``cpu_data.h`` : contains the public interface to Per CPU data structure.
157
158#. ``context_debug.h`` : contains public interface to report context memory
159 utilisation across the security states.
160
161#. ``context_el2.h`` : internal header consisting of helper macros to access EL2
162 context entries. Used by ``context.h``.
163
164Apart from these files, we have some context related source files under ``BL1``
165and ``BL31`` directory. ``bl1_context_mgmt.c`` ``bl31_context_mgmt.c``
166
167Bootloader Images utilizing Context Management Library
168======================================================
169
170+-------------------------------------------+-----------------------------+
171| Bootloader | Context Management Library |
172+-------------------------------------------+-----------------------------+
173| BL1 | Yes |
174+-------------------------------------------+-----------------------------+
175| BL2 | No |
176+-------------------------------------------+-----------------------------+
177| BL31 (Aarch64- EL3runtime firmware) | Yes |
178+-------------------------------------------+-----------------------------+
179| BL32 (Aarch32- EL3runtime firmware) | Yes |
180+-------------------------------------------+-----------------------------+
181
182CPU Data Structure
183==================
184For a given system, depending on the CPU count, the platform statically
185allocates memory for the CPU data structure.
186
187.. code:: c
188
189 /* The per_cpu_ptr_cache_t space allocation */
190 cpu_data_t percpu_data[PLATFORM_CORE_COUNT];
191
192This CPU data structure has a member element with an array of pointers to hold
193the Non-Secure, Realm and Secure security state context structures as listed below.
194
195.. code:: c
196
197 typedef struct cpu_data {
198 #ifdef __aarch64__
199 void *cpu_context[CPU_DATA_CONTEXT_NUM];
200 #endif
201
202 ....
203 ....
204
205 }cpu_data_t;
206
207|CPU Data Structure|
208
209At runtime, ``cpu_context[CPU_DATA_CONTEXT_NUM]`` array will be intitialised with
210the Secure, Non-Secure and Realm context structure addresses to ensure proper
211handling of the register state.
212See :ref:`Library APIs` section for more details.
213
214CPU Context and Memory allocation
215=================================
216
217CPU Context
218~~~~~~~~~~~
219The members of the context structure used by the EL3 firmware to preserve the
220state of CPU across exception levels for a given security state are listed below.
221
222.. code:: c
223
224 typedef struct cpu_context {
225 gp_regs_t gpregs_ctx;
226 el3_state_t el3state_ctx;
227 el1_sysregs_t el1_sysregs_ctx;
228
229 #if CTX_INCLUDE_EL2_REGS
230 el2_sysregs_t el2_sysregs_ctx;
231 #endif
232
233 #if CTX_INCLUDE_FPREGS
234 fp_regs_t fpregs_ctx;
235 #endif
236
237 cve_2018_3639_t cve_2018_3639_ctx;
238 #if CTX_INCLUDE_PAUTH_REGS
239 pauth_t pauth_ctx;
240 #endif
241
242 #if CTX_INCLUDE_MPAM_REGS
243 mpam_t mpam_ctx;
244 #endif
245
246 } cpu_context_t;
247
248Context Memory Allocation
249~~~~~~~~~~~~~~~~~~~~~~~~~
250
251CPUs maintain their context per world. The individual context memory allocation
252for each CPU per world is allocated by the world-specific dispatcher components
253at compile time as shown below.
254
255|Context memory allocation|
256
257NS-Context Memory
258~~~~~~~~~~~~~~~~~
259It's important to note that the Normal world doesn't possess the dispatcher
260component found in the Secure and Realm worlds. Instead, the PSCI library at EL3
261handles memory allocation for ``Non-Secure`` world context for all CPUs.
262
263.. code:: c
264
265 static cpu_context_t psci_ns_context[PLATFORM_CORE_COUNT];
266
267Secure-Context Memory
268~~~~~~~~~~~~~~~~~~~~~
269Secure World dispatcher (such as SPMD) at EL3 allocates the memory for ``Secure``
270world context of all CPUs.
271
272.. code:: c
273
274 static spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT];
275
276Realm-Context Memory
277~~~~~~~~~~~~~~~~~~~~
278Realm World dispatcher (RMMD) at EL3 allocates the memory for ``Realm`` world
279context of all CPUs.
280
281.. code:: c
282
283 rmmd_rmm_context_t rmm_context[PLATFORM_CORE_COUNT];
284
285To summarize, the world-specific context structures are synchronized with
286per-CPU data structures, which means that each CPU will have an array of pointers
287to individual worlds. The figure below illustrates the same.
288
289|CPU Context Memory Configuration|
290
291Context Setup/Initialization
292============================
293
294The CPU has been assigned context structures for every security state, which include
295Non-Secure, Secure and Realm. It is crucial to initialize each of these structures
296during the bootup of every CPU before they enter any security state for the
297first time. This section explains the specifics of how the initialization of
298every CPU context takes place during both cold and warm boot paths.
299
300Context Setup during Cold boot
301~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
302The cold boot path is mainly executed by the primary CPU, other than essential
303CPU initialization executed by all CPUs. After executing BL1 and BL2, the Primary
304CPU jumps to the BL31 image for runtime services initialization.
305During this process, the per_cpu_data structure gets initialized with statically
306allocated world-specific context memory.
307
308Later in the cold boot sequence, the BL31 image at EL3 checks for the presence
309of a Secure world image at S-EL2. If detected, it invokes the secure context
310initialization sequence under SPMD. Additionally, based on RME enablement,
311the Realm context gets initialized from the RMMD at EL3. Finally, before exiting
312to the normal world, the Non-Secure context gets initialized via the context
313management library. At this stage, all Primary CPU contexts are initialized
314and the CPU exits EL3 to enter the Normal world.
315
316|Context Init ColdBoot|
317
318.. note::
319 The figure above illustrates a scenario on FVP for one of the build
320 configurations with TFTF component at NS-EL2.
321
322Context Setup during Warmboot
323~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
324
325During a warm boot sequence, the primary CPU is responsible for powering on the
326secondary CPUs. Refer to :ref:`CPU Reset` and :ref:`Firmware Design` sections for
327more details on the warm boot.
328
329|Context Init WarmBoot|
330
331The primary CPU initializes the Non-Secure context for the secondary CPU while
332restoring re-entry information for the Non-Secure world.
333It initialises via ``cm_init_context_by_index(target_idx, ep )``.
334
335``psci_warmboot_entrypoint()`` is the warm boot entrypoint procedure.
336During the warm bootup process, secondary CPUs have their secure context
337initialized through SPMD at EL3. Upon successful SP initialization, the SPD
338power management operations become shared with the PSCI library. During this
339process, the SPMD duly registers its handlers with the PSCI library.
340
341.. code:: c
342
343 file: psci_common.c
344 const spd_pm_ops_t *psci_spd_pm;
345
346 file: spmd_pm.c
347 const spd_pm_ops_t spmd_pm = {
348 .svc_on_finish = spmd_cpu_on_finish_handler,
349 .svc_off = spmd_cpu_off_handler
350 }
351
352Secondary CPUs during their bootup in the ``psci_cpu_on_finish()`` routine get
353their secure context initialised via the registered SPMD handler
354``spmd_cpu_on_finish_handler()`` at EL3.
355The figure above illustrates the same with reference of Primary CPU running at
356NS-EL2.
357
358.. _Library APIs:
359
360Library APIs
361============
362
363The public APIs and types can be found in ``include/lib/el3_runtime/context_management.h``
364and this section is intended to provide additional details and clarifications.
365
366Context Initialization for Individual Worlds
367~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
368The library implements high level APIs for the CPUs in setting up their individual
369context for each world (Non-Secure, Secure and Realm).
370
371.. c:function:: static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *ep);
372
373This function is responsible for the general context initialization that applies
374to all worlds. It will be invoked first, before calling the individual
375world-specific context setup APIs.
376
377.. c:function:: static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *ep);
378.. c:function:: static void setup_realm_context(cpu_context_t *ctx, const struct entry_point_info *ep);
379.. c:function:: static void setup_secure_context(cpu_context_t *ctx, const struct entry_point_info *ep);
380
381Depending on the security state that the CPU needs to enter, the respective
382world-specific context setup handlers listed above will be invoked once per-CPU
383to set up the context for their execution.
384
385.. c:function:: void cm_manage_extensions_el3(void)
386
387This function initializes all EL3 registers whose values do not change during the
388lifetime of EL3 runtime firmware. It is invoked from each CPU via the cold boot
389path ``bl31_main()`` and in the WarmBoot entry path ``void psci_warmboot_entrypoint()``.
390
391Runtime Save and Restore of Registers
392~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
393
394EL1 Registers
395-------------
396
397.. c:function:: void cm_el1_sysregs_context_save(uint32_t security_state);
398.. c:function:: void cm_el1_sysregs_context_restore(uint32_t security_state);
399
400These functions are utilized by the world-specific dispatcher components running
401at EL3 to facilitate the saving and restoration of the EL1 system registers
402during a world switch.
403
404EL2 Registers
405-------------
406
407.. c:function:: void cm_el2_sysregs_context_save(uint32_t security_state);
408.. c:function:: void cm_el2_sysregs_context_restore(uint32_t security_state);
409
410These functions are utilized by the world-specific dispatcher components running
411at EL3 to facilitate the saving and restoration of the EL2 system registers
412during a world switch.
413
414Pauth Registers
415---------------
416
417Pointer Authentication feature is enabled by default for Non-Secure world and
418disabled for Secure and Realm worlds. In this case, we don't need to explicitly
419save and restore the Pauth registers during world switch.
420However, ``CTX_INCLUDE_PAUTH_REGS`` flag is explicitly used to enable Pauth for
421lower exception levels of Secure and Realm worlds. In this scenario, we save the
422general purpose and Pauth registers while we enter EL3 from lower ELs via
423``prepare_el3_entry`` and restore them back while we exit EL3 to lower ELs
424via ``el3_exit``.
425
426.. code:: c
427
428 .macro save_gp_pmcr_pauth_regs
429 func restore_gp_pmcr_pauth_regs
430
431Feature Enablement for Individual Worlds
432~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
433
434.. c:function:: static void manage_extensions_nonsecure(cpu_context_t *ctx);
435.. c:function:: static void manage_extensions_secure(cpu_context_t *ctx);
436.. c:function:: static void manage_extensions_realm(cpu_context_t *ctx)
437
438Functions that allow the enabling and disabling of architectural features for
439each security state. These functions are invoked from the top-level setup APIs
440during context initialization.
441
442Further, a pattern is established for feature enablement code (AArch64).
443Each feature implements following APIs as applicable:
444Note: (``xxx`` is the name of the feature in the APIs)
445
446- ``is_feat_xxx_supported()`` and ``is_feat_xxx_present()`` - mandatory for all features.
447
448- ``xxx_enable(cpu_context * )`` and ``xxx_disable(cpu_context * )`` - optional
449 functions to enable the feature for the passed context only. To be called in
450 the respective world's setup_context to select behaviour.
451
452- ``xxx_init_el3()`` - optional function to enable the feature in-place in any EL3
453 registers that are never context switched. The values they write must never
454 change, otherwise the functions mentioned in previous point should be used.
455 Invoked from ``cm_manage_extensions_el3()``.
456
457- ``xxx_init_el2_unused()`` - optional function to enable the feature in-place
458 in any EL2 registers that are necessary for execution in EL1 with no EL2 present.
459
460The above mentioned rules, followed for ``FEAT_SME`` is shown below:
461
462.. code:: c
463
464 void sme_enable(cpu_context_t *context);
465 void sme_init_el3(void);
466 void sme_init_el2_unused(void);
467 void sme_disable(cpu_context_t *context);
468
469Per-world Context
470=================
471
472Apart from the CPU context structure, we have another structure to manage some
473of the EL3 system registers whose values are identical across all the CPUs
474referred to as ``per_world_context_t``.
475The Per-world context structure is intended for managing EL3 system registers with
476identical values across all CPUs, requiring only a singular context entry for each
477individual world. This structure operates independently of the CPU context
478structure and is intended to manage specific EL3 registers.
479
480.. code-block:: c
481
482 typedef struct per_world_context {
483 uint64_t ctx_cptr_el3;
484 uint64_t ctx_zcr_el3;
485 uint64_t ctx_mpam3_el3;
486 } per_world_context_t;
487
488These functions facilitate the activation of architectural extensions that possess
489identical values across all cores for the individual Non-secure, Secure, and
490Realm worlds.
491
492*Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.*
493
494.. |Context Memory Allocation| image:: ../resources/diagrams/context_memory_allocation.png
495.. |CPU Context Memory Configuration| image:: ../resources/diagrams/cpu_data_config_context_memory.png
496.. |CPU Data Structure| image:: ../resources/diagrams/percpu-data-struct.png
497.. |Context Init ColdBoot| image:: ../resources/diagrams/context_init_coldboot.png
498.. |Context Init WarmBoot| image:: ../resources/diagrams/context_init_warmboot.png
499.. _Trustzone for AArch64: https://developer.arm.com/documentation/102418/0101/TrustZone-in-the-processor/Switching-between-Security-states
500.. _Security States with RME: https://developer.arm.com/documentation/den0126/0100/Security-states
501.. _lib/el3_runtime/(aarch32/aarch64): https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/lib/el3_runtime