sdei.rst 16 KB

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