Paul Beesley | ea22512 | 2019-02-11 17:54:45 +0000 | [diff] [blame] | 1 | SDEI: Software Delegated Exception Interface |
| 2 | ============================================ |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 3 | |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 4 | This document provides an overview of the SDEI dispatcher implementation in |
| 5 | Trusted Firmware-A (TF-A). |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 6 | |
| 7 | Introduction |
| 8 | ------------ |
| 9 | |
Paul Beesley | f864067 | 2019-04-12 14:19:42 +0100 | [diff] [blame] | 10 | Software Delegated Exception Interface (|SDEI|) is an Arm specification for |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 11 | Non-secure world to register handlers with firmware to receive notifications |
| 12 | about system events. Firmware will first receive the system events by way of |
| 13 | asynchronous exceptions and, in response, arranges for the registered handler to |
| 14 | execute in the Non-secure EL. |
| 15 | |
| 16 | Normal world software that interacts with the SDEI dispatcher (makes SDEI |
| 17 | requests and receives notifications) is referred to as the *SDEI Client*. A |
| 18 | client receives the event notification at the registered handler even when it |
| 19 | was executing with exceptions masked. The list of SDEI events available to the |
| 20 | client are specific to the platform [#std-event]_. See also `Determining client |
| 21 | EL`_. |
| 22 | |
| 23 | .. _general SDEI dispatch: |
| 24 | |
| 25 | The following figure depicts a general sequence involving SDEI client executing |
| 26 | at EL2 and an event dispatch resulting from the triggering of a bound interrupt. |
| 27 | A commentary is provided below: |
| 28 | |
Paul Beesley | 8c178b5 | 2019-07-12 11:56:58 +0100 | [diff] [blame] | 29 | .. uml:: ../resources/diagrams/plantuml/sdei_general.puml |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 30 | |
| 31 | As part of initialisation, the SDEI client binds a Non-secure interrupt [1], and |
| 32 | the SDEI dispatcher returns a platform dynamic event number [2]. The client then |
| 33 | registers a handler for that event [3], enables the event [5], and unmasks all |
| 34 | events on the current PE [7]. This sequence is typical of an SDEI client, but it |
| 35 | may involve additional SDEI calls. |
| 36 | |
| 37 | At a later point in time, when the bound interrupt triggers [9], it's trapped to |
| 38 | EL3. The interrupt is handed over to the SDEI dispatcher, which then arranges to |
| 39 | execute the registered handler [10]. The client terminates its execution with |
| 40 | ``SDEI_EVENT_COMPLETE`` [11], following which the dispatcher resumes the |
| 41 | original EL2 execution [13]. Note that the SDEI interrupt remains active until |
| 42 | the client handler completes, at which point EL3 does EOI [12]. |
| 43 | |
John Tsichritzis | e14a9bb | 2019-05-28 12:45:06 +0100 | [diff] [blame] | 44 | Other than events bound to interrupts, as depicted in the sequence above, SDEI |
Jeenu Viswambharan | 3439230 | 2018-01-17 12:30:11 +0000 | [diff] [blame] | 45 | events can be explicitly dispatched in response to other exceptions, for |
| 46 | example, upon receiving an *SError* or *Synchronous External Abort*. See |
| 47 | `Explicit dispatch of events`_. |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 48 | |
| 49 | The remainder of this document only discusses the design and implementation of |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 50 | SDEI dispatcher in TF-A, and assumes that the reader is familiar with the SDEI |
| 51 | specification, the interfaces, and their requirements. |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 52 | |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 53 | Defining events |
| 54 | --------------- |
| 55 | |
| 56 | A platform choosing to include the SDEI dispatcher must also define the events |
| 57 | available on the platform, along with their attributes. |
| 58 | |
| 59 | The platform is expected to provide two arrays of event descriptors: one for |
| 60 | private events, and another for shared events. The SDEI dispatcher provides |
| 61 | ``SDEI_PRIVATE_EVENT()`` and ``SDEI_SHARED_EVENT()`` macros to populate the |
| 62 | event descriptors. Both macros take 3 arguments: |
| 63 | |
| 64 | - The event number: this must be a positive 32-bit integer. |
| 65 | |
Jeenu Viswambharan | 3439230 | 2018-01-17 12:30:11 +0000 | [diff] [blame] | 66 | - For an event that has a backing interrupt, the interrupt number the event is |
| 67 | bound to: |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 68 | |
| 69 | - If it's not applicable to an event, this shall be left as ``0``. |
| 70 | |
| 71 | - If the event is dynamic, this should be specified as ``SDEI_DYN_IRQ``. |
| 72 | |
| 73 | - A bit map of `Event flags`_. |
| 74 | |
| 75 | To define event 0, the macro ``SDEI_DEFINE_EVENT_0()`` should be used. This |
| 76 | macro takes only one parameter: an SGI number to signal other PEs. |
| 77 | |
Paul Beesley | f864067 | 2019-04-12 14:19:42 +0100 | [diff] [blame] | 78 | To define an event that's meant to be explicitly dispatched (i.e., not as a |
Jeenu Viswambharan | 3439230 | 2018-01-17 12:30:11 +0000 | [diff] [blame] | 79 | result of receiving an SDEI interrupt), the macro ``SDEI_EXPLICIT_EVENT()`` |
| 80 | should be used. It accepts two parameters: |
| 81 | |
Jeenu Viswambharan | 3439230 | 2018-01-17 12:30:11 +0000 | [diff] [blame] | 82 | - The event number (as above); |
| 83 | |
| 84 | - Event priority: ``SDEI_MAPF_CRITICAL`` or ``SDEI_MAPF_NORMAL``, as described |
| 85 | below. |
| 86 | |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 87 | Once the event descriptor arrays are defined, they should be exported to the |
| 88 | SDEI dispatcher using the ``REGISTER_SDEI_MAP()`` macro, passing it the pointers |
| 89 | to the private and shared event descriptor arrays, respectively. Note that the |
| 90 | ``REGISTER_SDEI_MAP()`` macro must be used in the same file where the arrays are |
| 91 | defined. |
| 92 | |
| 93 | Regarding event descriptors: |
| 94 | |
| 95 | - For Event 0: |
| 96 | |
| 97 | - There must be exactly one descriptor in the private array, and none in the |
| 98 | shared array. |
| 99 | |
| 100 | - The event should be defined using ``SDEI_DEFINE_EVENT_0()``. |
| 101 | |
| 102 | - Must be bound to a Secure SGI on the platform. |
| 103 | |
Jeenu Viswambharan | 3439230 | 2018-01-17 12:30:11 +0000 | [diff] [blame] | 104 | - Explicit events should only be used in the private array. |
| 105 | |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 106 | - Statically bound shared and private interrupts must be bound to shared and |
| 107 | private interrupts on the platform, respectively. See the section on |
Paul Beesley | f864067 | 2019-04-12 14:19:42 +0100 | [diff] [blame] | 108 | `Configuration within Exception Handling Framework`_. |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 109 | |
| 110 | - Both arrays should be one-dimensional. The ``REGISTER_SDEI_MAP()`` macro |
| 111 | takes care of replicating private events for each PE on the platform. |
| 112 | |
| 113 | - Both arrays must be sorted in the increasing order of event number. |
| 114 | |
| 115 | The SDEI specification doesn't have provisions for discovery of available events |
| 116 | on the platform. The list of events made available to the client, along with |
| 117 | their semantics, have to be communicated out of band; for example, through |
| 118 | Device Trees or firmware configuration tables. |
| 119 | |
| 120 | See also `Event definition example`_. |
| 121 | |
| 122 | Event flags |
| 123 | ~~~~~~~~~~~ |
| 124 | |
| 125 | Event flags describe the properties of the event. They are bit maps that can be |
Paul Beesley | f864067 | 2019-04-12 14:19:42 +0100 | [diff] [blame] | 126 | ``OR``\ ed to form parameters to macros that define events (see |
| 127 | `Defining events`_). |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 128 | |
| 129 | - ``SDEI_MAPF_DYNAMIC``: Marks the event as dynamic. Dynamic events can be |
Antonio Nino Diaz | 56b68ad | 2019-02-28 13:35:21 +0000 | [diff] [blame] | 130 | bound to (or released from) any Non-secure interrupt at runtime via the |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 131 | ``SDEI_INTERRUPT_BIND`` and ``SDEI_INTERRUPT_RELEASE`` calls. |
| 132 | |
| 133 | - ``SDEI_MAPF_BOUND``: Marks the event as statically bound to an interrupt. |
| 134 | These events cannot be re-bound at runtime. |
| 135 | |
Jeenu Viswambharan | 3439230 | 2018-01-17 12:30:11 +0000 | [diff] [blame] | 136 | - ``SDEI_MAPF_NORMAL``: Marks the event as having *Normal* priority. This is |
| 137 | the default priority. |
| 138 | |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 139 | - ``SDEI_MAPF_CRITICAL``: Marks the event as having *Critical* priority. |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 140 | |
| 141 | Event definition example |
| 142 | ------------------------ |
| 143 | |
| 144 | .. code:: c |
| 145 | |
| 146 | static sdei_ev_map_t plat_private_sdei[] = { |
| 147 | /* Event 0 definition */ |
| 148 | SDEI_DEFINE_EVENT_0(8), |
| 149 | |
| 150 | /* PPI */ |
| 151 | SDEI_PRIVATE_EVENT(8, 23, SDEI_MAPF_BOUND), |
| 152 | |
| 153 | /* Dynamic private events */ |
| 154 | SDEI_PRIVATE_EVENT(100, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), |
| 155 | SDEI_PRIVATE_EVENT(101, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC) |
Jeenu Viswambharan | 3439230 | 2018-01-17 12:30:11 +0000 | [diff] [blame] | 156 | |
| 157 | /* Events for explicit dispatch */ |
| 158 | SDEI_EXPLICIT_EVENT(2000, SDEI_MAPF_NORMAL); |
| 159 | SDEI_EXPLICIT_EVENT(2000, SDEI_MAPF_CRITICAL); |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 160 | }; |
| 161 | |
| 162 | /* Shared event mappings */ |
| 163 | static sdei_ev_map_t plat_shared_sdei[] = { |
| 164 | SDEI_SHARED_EVENT(804, 0, SDEI_MAPF_DYNAMIC), |
| 165 | |
| 166 | /* Dynamic shared events */ |
| 167 | SDEI_SHARED_EVENT(3000, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), |
| 168 | SDEI_SHARED_EVENT(3001, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC) |
| 169 | }; |
| 170 | |
| 171 | /* Export SDEI events */ |
| 172 | REGISTER_SDEI_MAP(plat_private_sdei, plat_shared_sdei); |
| 173 | |
| 174 | Configuration within Exception Handling Framework |
| 175 | ------------------------------------------------- |
| 176 | |
| 177 | The SDEI dispatcher functions alongside the Exception Handling Framework. This |
| 178 | means that the platform must assign priorities to both Normal and Critical SDEI |
| 179 | interrupts for the platform: |
| 180 | |
| 181 | - Install priority descriptors for Normal and Critical SDEI interrupts. |
| 182 | |
| 183 | - For those interrupts that are statically bound (i.e. events defined as having |
| 184 | the ``SDEI_MAPF_BOUND`` property), enumerate their properties for the GIC |
| 185 | driver to configure interrupts accordingly. |
| 186 | |
| 187 | The interrupts must be configured to target EL3. This means that they should |
| 188 | be configured as *Group 0*. Additionally, on GICv2 systems, the build option |
| 189 | ``GICV2_G0_FOR_EL3`` must be set to ``1``. |
| 190 | |
Paul Beesley | f864067 | 2019-04-12 14:19:42 +0100 | [diff] [blame] | 191 | See also :ref:`porting_guide_sdei_requirements`. |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 192 | |
| 193 | Determining client EL |
| 194 | --------------------- |
| 195 | |
| 196 | The SDEI specification requires that the *physical* SDEI client executes in the |
| 197 | highest Non-secure EL implemented on the system. This means that the dispatcher |
| 198 | will only allow SDEI calls to be made from: |
| 199 | |
| 200 | - EL2, if EL2 is implemented. The Hypervisor is expected to implement a |
| 201 | *virtual* SDEI dispatcher to support SDEI clients in Guest Operating Systems |
| 202 | executing in Non-secure EL1. |
| 203 | |
| 204 | - Non-secure EL1, if EL2 is not implemented or disabled. |
| 205 | |
| 206 | See the function ``sdei_client_el()`` in ``sdei_private.h``. |
| 207 | |
Madhukar Pappireddy | 86350ae | 2020-07-29 09:37:25 -0500 | [diff] [blame] | 208 | .. _explicit-dispatch-of-events: |
| 209 | |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 210 | Explicit dispatch of events |
| 211 | --------------------------- |
| 212 | |
| 213 | Typically, an SDEI event dispatch is caused by the PE receiving interrupts that |
| 214 | are bound to an SDEI event. However, there are cases where the Secure world |
| 215 | requires dispatch of an SDEI event as a direct or indirect result of a past |
Antonio Nino Diaz | 56b68ad | 2019-02-28 13:35:21 +0000 | [diff] [blame] | 216 | activity, such as receiving a Secure interrupt or an exception. |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 217 | |
| 218 | The SDEI dispatcher implementation provides ``sdei_dispatch_event()`` API for |
| 219 | this purpose. The API has the following signature: |
| 220 | |
Paul Beesley | 493e349 | 2019-03-13 15:11:04 +0000 | [diff] [blame] | 221 | .. code:: c |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 222 | |
Jeenu Viswambharan | 8b7e6bc | 2018-02-16 12:07:48 +0000 | [diff] [blame] | 223 | int sdei_dispatch_event(int ev_num); |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 224 | |
Jeenu Viswambharan | 8b7e6bc | 2018-02-16 12:07:48 +0000 | [diff] [blame] | 225 | The parameter ``ev_num`` is the event number to dispatch. The API returns ``0`` |
| 226 | on success, or ``-1`` on failure. |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 227 | |
| 228 | The following figure depicts a scenario involving explicit dispatch of SDEI |
| 229 | event. A commentary is provided below: |
| 230 | |
Paul Beesley | 8c178b5 | 2019-07-12 11:56:58 +0100 | [diff] [blame] | 231 | .. uml:: ../resources/diagrams/plantuml/sdei_explicit_dispatch.puml |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 232 | |
| 233 | As part of initialisation, the SDEI client registers a handler for a platform |
| 234 | event [1], enables the event [3], and unmasks the current PE [5]. Note that, |
| 235 | unlike in `general SDEI dispatch`_, this doesn't involve interrupt binding, as |
| 236 | bound or dynamic events can't be explicitly dispatched (see the section below). |
| 237 | |
| 238 | At a later point in time, a critical event [#critical-event]_ is trapped into |
Jeenu Viswambharan | 8b7e6bc | 2018-02-16 12:07:48 +0000 | [diff] [blame] | 239 | EL3 [7]. EL3 performs a first-level triage of the event, and a RAS component |
| 240 | assumes further handling [8]. The dispatch completes, but intends to involve |
| 241 | Non-secure world in further handling, and therefore decides to explicitly |
| 242 | dispatch an event [10] (which the client had already registered for [1]). The |
| 243 | rest of the sequence is similar to that in the `general SDEI dispatch`_: the |
| 244 | requested event is dispatched to the client (assuming all the conditions are |
| 245 | met), and when the handler completes, the preempted execution resumes. |
Jeenu Viswambharan | 9a62fd1 | 2017-11-16 12:34:15 +0000 | [diff] [blame] | 246 | |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 247 | Conditions for event dispatch |
| 248 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 249 | |
| 250 | All of the following requirements must be met for the API to return ``0`` and |
| 251 | event to be dispatched: |
| 252 | |
| 253 | - SDEI events must be unmasked on the PE. I.e. the client must have called |
| 254 | ``PE_UNMASK`` beforehand. |
| 255 | |
| 256 | - Event 0 can't be dispatched. |
| 257 | |
Jeenu Viswambharan | 3439230 | 2018-01-17 12:30:11 +0000 | [diff] [blame] | 258 | - The event must be declared using the ``SDEI_EXPLICIT_EVENT()`` macro |
| 259 | described above. |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 260 | |
| 261 | - The event must be private to the PE. |
| 262 | |
| 263 | - The event must have been registered for and enabled. |
| 264 | |
| 265 | - A dispatch for the same event must not be outstanding. I.e. it hasn't already |
| 266 | been dispatched and is yet to be completed. |
| 267 | |
| 268 | - The priority of the event (either Critical or Normal, as configured by the |
| 269 | platform at build-time) shouldn't cause priority inversion. This means: |
| 270 | |
| 271 | - If it's of Normal priority, neither Normal nor Critical priority dispatch |
| 272 | must be outstanding on the PE. |
| 273 | |
| 274 | - If it's of a Critical priority, no Critical priority dispatch must be |
| 275 | outstanding on the PE. |
| 276 | |
| 277 | Further, the caller should be aware of the following assumptions made by the |
| 278 | dispatcher: |
| 279 | |
Jeenu Viswambharan | 8b7e6bc | 2018-02-16 12:07:48 +0000 | [diff] [blame] | 280 | - The caller of the API is a component running in EL3; for example, a RAS |
| 281 | driver. |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 282 | |
| 283 | - The requested dispatch will be permitted by the Exception Handling Framework. |
| 284 | I.e. the caller must make sure that the requested dispatch has sufficient |
| 285 | priority so as not to cause priority level inversion within Exception |
| 286 | Handling Framework. |
| 287 | |
Jeenu Viswambharan | 8b7e6bc | 2018-02-16 12:07:48 +0000 | [diff] [blame] | 288 | - The caller must be prepared for the SDEI dispatcher to restore the Non-secure |
| 289 | context, and mark that the active context. |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 290 | |
Jeenu Viswambharan | 8b7e6bc | 2018-02-16 12:07:48 +0000 | [diff] [blame] | 291 | - The call will block until the SDEI client completes the event (i.e. when the |
| 292 | client calls either ``SDEI_EVENT_COMPLETE`` or ``SDEI_COMPLETE_AND_RESUME``). |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 293 | |
Jeenu Viswambharan | 8b7e6bc | 2018-02-16 12:07:48 +0000 | [diff] [blame] | 294 | - The caller must be prepared for this API to return failure and handle |
| 295 | accordingly. |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 296 | |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 297 | Porting requirements |
| 298 | -------------------- |
| 299 | |
Paul Beesley | f864067 | 2019-04-12 14:19:42 +0100 | [diff] [blame] | 300 | The porting requirements of the SDEI dispatcher are outlined in the |
| 301 | :ref:`Porting Guide <porting_guide_sdei_requirements>`. |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 302 | |
| 303 | Note on writing SDEI event handlers |
| 304 | ----------------------------------- |
| 305 | |
| 306 | *This section pertains to SDEI event handlers in general, not just when using |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 307 | the TF-A SDEI dispatcher.* |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 308 | |
| 309 | The SDEI specification requires that event handlers preserve the contents of all |
| 310 | registers except ``x0`` to ``x17``. This has significance if event handler is |
| 311 | written in C: compilers typically adjust the stack frame at the beginning and |
| 312 | end of C functions. For example, AArch64 GCC typically produces the following |
| 313 | function prologue and epilogue: |
| 314 | |
| 315 | :: |
| 316 | |
| 317 | c_event_handler: |
| 318 | stp x29, x30, [sp,#-32]! |
| 319 | mov x29, sp |
| 320 | |
| 321 | ... |
| 322 | |
| 323 | bl ... |
| 324 | |
| 325 | ... |
| 326 | |
| 327 | ldp x29, x30, [sp],#32 |
| 328 | ret |
| 329 | |
| 330 | The register ``x29`` is used as frame pointer in the prologue. Because neither a |
| 331 | valid ``SDEI_EVENT_COMPLETE`` nor ``SDEI_EVENT_COMPLETE_AND_RESUME`` calls |
| 332 | return to the handler, the epilogue never gets executed, and registers ``x29`` |
| 333 | and ``x30`` (in the case above) are inadvertently corrupted. This violates the |
| 334 | SDEI specification, and the normal execution thereafter will result in |
| 335 | unexpected behaviour. |
| 336 | |
| 337 | To work this around, it's advised that the top-level event handlers are |
| 338 | implemented in assembly, following a similar pattern as below: |
| 339 | |
| 340 | :: |
| 341 | |
| 342 | asm_event_handler: |
| 343 | /* Save link register whilst maintaining stack alignment */ |
| 344 | stp xzr, x30, [sp, #-16]! |
| 345 | bl c_event_handler |
| 346 | |
| 347 | /* Restore link register */ |
| 348 | ldp xzr, x30, [sp], #16 |
| 349 | |
| 350 | /* Complete call */ |
| 351 | ldr x0, =SDEI_EVENT_COMPLETE |
| 352 | smc #0 |
| 353 | b . |
| 354 | |
Paul Beesley | f864067 | 2019-04-12 14:19:42 +0100 | [diff] [blame] | 355 | -------------- |
| 356 | |
Manish Pandey | b074021 | 2024-01-11 16:06:29 +0000 | [diff] [blame] | 357 | Security Considerations |
| 358 | ----------------------- |
| 359 | |
| 360 | SDEI introduces concept of providing software based non-maskable interrupts to |
| 361 | Hypervisor/OS. In doing so, it modifies the priority scheme defined by Interrupt |
| 362 | controllers and relies on Non-Secure clients, Hypervisor or OS, to create/manage |
| 363 | high priority events. |
| 364 | |
| 365 | Considering a Non-secure client is involved in SDEI state management, there exists |
| 366 | some security considerations which needs to be taken care of in both client and EL3 |
| 367 | when using SDEI. Few of them are mentioned below. |
| 368 | |
| 369 | Bound events |
| 370 | ~~~~~~~~~~~~ |
| 371 | |
| 372 | A bound event is an SDEI event that corresponds to a client interrupt. |
| 373 | The binding of event is done using ``SDEI_INTERRUPT_BIND`` SMC call to associate |
| 374 | an SDEI event with a client interrupt. There is a possibility that a rogue |
| 375 | client can request an invalid interrupt to be bound. This may potentially |
| 376 | cause out-of-bound memory read. |
| 377 | |
| 378 | Even though TF-A implementation has checks to ensure that interrupt ID passed |
| 379 | by client is architecturally valid, Non-secure client should also ensure the |
| 380 | validity of interrupts. |
| 381 | |
| 382 | Recurring events |
| 383 | ~~~~~~~~~~~~~~~~ |
| 384 | |
| 385 | For a given event source, if the events are generated continuously, then NS client |
| 386 | may be unusable. To mitigate against this, the Non-secure client must have |
| 387 | mechanism in place to remove such interrupt source from the system. |
| 388 | |
| 389 | One of the examples is a memory region which continuously generates RAS errors. |
| 390 | This may result in unusable Non-secure client. |
| 391 | |
| 392 | Dispatched events |
| 393 | ~~~~~~~~~~~~~~~~~ |
| 394 | |
| 395 | For a dispatched event, it is the client's responsibility to ensure that the |
| 396 | handling finishes in finite time and notify the dispatcher through |
| 397 | ``SDEI_EVENT_COMPLETE`` or ``SDEI_EVENT_COMPLETE_AND_RESUME``. If the client |
| 398 | fails to complete the event handling, it might result in ``UNPREDICTABLE`` behavior |
| 399 | in the client and potentially end up in unusable PE. |
| 400 | |
| 401 | *Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.* |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 402 | |
Paul Beesley | f864067 | 2019-04-12 14:19:42 +0100 | [diff] [blame] | 403 | .. rubric:: Footnotes |
| 404 | |
| 405 | .. [#std-event] Except event 0, which is defined by the SDEI specification as a |
| 406 | standard event. |
| 407 | |
| 408 | .. [#critical-event] Examples of critical events are *SError*, *Synchronous |
| 409 | External Abort*, *Fault Handling interrupt* or *Error |
| 410 | Recovery interrupt* from one of RAS nodes in the system. |
Jeenu Viswambharan | db5e12e | 2017-10-18 14:35:20 +0100 | [diff] [blame] | 411 | |
| 412 | .. _SDEI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf |
John Tsichritzis | e14a9bb | 2019-05-28 12:45:06 +0100 | [diff] [blame] | 413 | .. _Software Delegated Exception Interface: `SDEI specification`_ |