blob: 309375f9390fe6349b290c33ea96f3389ed20045 [file] [log] [blame]
Paul Beesleyea225122019-02-11 17:54:45 +00001SDEI: Software Delegated Exception Interface
2============================================
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +01003
Dan Handley610e7e12018-03-01 18:44:00 +00004This document provides an overview of the SDEI dispatcher implementation in
5Trusted Firmware-A (TF-A).
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +01006
7Introduction
8------------
9
Paul Beesleyf8640672019-04-12 14:19:42 +010010Software Delegated Exception Interface (|SDEI|) is an Arm specification for
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +010011Non-secure world to register handlers with firmware to receive notifications
12about system events. Firmware will first receive the system events by way of
13asynchronous exceptions and, in response, arranges for the registered handler to
14execute in the Non-secure EL.
15
16Normal world software that interacts with the SDEI dispatcher (makes SDEI
17requests and receives notifications) is referred to as the *SDEI Client*. A
18client receives the event notification at the registered handler even when it
19was executing with exceptions masked. The list of SDEI events available to the
20client are specific to the platform [#std-event]_. See also `Determining client
21EL`_.
22
23.. _general SDEI dispatch:
24
25The following figure depicts a general sequence involving SDEI client executing
26at EL2 and an event dispatch resulting from the triggering of a bound interrupt.
27A commentary is provided below:
28
Paul Beesley8c178b52019-07-12 11:56:58 +010029.. uml:: ../resources/diagrams/plantuml/sdei_general.puml
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +010030
31As part of initialisation, the SDEI client binds a Non-secure interrupt [1], and
32the SDEI dispatcher returns a platform dynamic event number [2]. The client then
33registers a handler for that event [3], enables the event [5], and unmasks all
34events on the current PE [7]. This sequence is typical of an SDEI client, but it
35may involve additional SDEI calls.
36
37At a later point in time, when the bound interrupt triggers [9], it's trapped to
38EL3. The interrupt is handed over to the SDEI dispatcher, which then arranges to
39execute the registered handler [10]. The client terminates its execution with
40``SDEI_EVENT_COMPLETE`` [11], following which the dispatcher resumes the
41original EL2 execution [13]. Note that the SDEI interrupt remains active until
42the client handler completes, at which point EL3 does EOI [12].
43
John Tsichritzise14a9bb2019-05-28 12:45:06 +010044Other than events bound to interrupts, as depicted in the sequence above, SDEI
Jeenu Viswambharan34392302018-01-17 12:30:11 +000045events can be explicitly dispatched in response to other exceptions, for
46example, upon receiving an *SError* or *Synchronous External Abort*. See
47`Explicit dispatch of events`_.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +010048
49The remainder of this document only discusses the design and implementation of
Dan Handley610e7e12018-03-01 18:44:00 +000050SDEI dispatcher in TF-A, and assumes that the reader is familiar with the SDEI
51specification, the interfaces, and their requirements.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +010052
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +010053Defining events
54---------------
55
56A platform choosing to include the SDEI dispatcher must also define the events
57available on the platform, along with their attributes.
58
59The platform is expected to provide two arrays of event descriptors: one for
60private events, and another for shared events. The SDEI dispatcher provides
61``SDEI_PRIVATE_EVENT()`` and ``SDEI_SHARED_EVENT()`` macros to populate the
62event descriptors. Both macros take 3 arguments:
63
64- The event number: this must be a positive 32-bit integer.
65
Jeenu Viswambharan34392302018-01-17 12:30:11 +000066- For an event that has a backing interrupt, the interrupt number the event is
67 bound to:
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +010068
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
75To define event 0, the macro ``SDEI_DEFINE_EVENT_0()`` should be used. This
76macro takes only one parameter: an SGI number to signal other PEs.
77
Paul Beesleyf8640672019-04-12 14:19:42 +010078To define an event that's meant to be explicitly dispatched (i.e., not as a
Jeenu Viswambharan34392302018-01-17 12:30:11 +000079result of receiving an SDEI interrupt), the macro ``SDEI_EXPLICIT_EVENT()``
80should be used. It accepts two parameters:
81
Jeenu Viswambharan34392302018-01-17 12:30:11 +000082- The event number (as above);
83
84- Event priority: ``SDEI_MAPF_CRITICAL`` or ``SDEI_MAPF_NORMAL``, as described
85 below.
86
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +010087Once the event descriptor arrays are defined, they should be exported to the
88SDEI dispatcher using the ``REGISTER_SDEI_MAP()`` macro, passing it the pointers
89to 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
91defined.
92
93Regarding 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 Viswambharan34392302018-01-17 12:30:11 +0000104- Explicit events should only be used in the private array.
105
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100106- Statically bound shared and private interrupts must be bound to shared and
107 private interrupts on the platform, respectively. See the section on
Paul Beesleyf8640672019-04-12 14:19:42 +0100108 `Configuration within Exception Handling Framework`_.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100109
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
115The SDEI specification doesn't have provisions for discovery of available events
116on the platform. The list of events made available to the client, along with
117their semantics, have to be communicated out of band; for example, through
118Device Trees or firmware configuration tables.
119
120See also `Event definition example`_.
121
122Event flags
123~~~~~~~~~~~
124
125Event flags describe the properties of the event. They are bit maps that can be
Paul Beesleyf8640672019-04-12 14:19:42 +0100126``OR``\ ed to form parameters to macros that define events (see
127`Defining events`_).
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100128
129- ``SDEI_MAPF_DYNAMIC``: Marks the event as dynamic. Dynamic events can be
Antonio Nino Diaz56b68ad2019-02-28 13:35:21 +0000130 bound to (or released from) any Non-secure interrupt at runtime via the
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100131 ``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 Viswambharan34392302018-01-17 12:30:11 +0000136- ``SDEI_MAPF_NORMAL``: Marks the event as having *Normal* priority. This is
137 the default priority.
138
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100139- ``SDEI_MAPF_CRITICAL``: Marks the event as having *Critical* priority.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100140
141Event 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 Viswambharan34392302018-01-17 12:30:11 +0000156
157 /* Events for explicit dispatch */
158 SDEI_EXPLICIT_EVENT(2000, SDEI_MAPF_NORMAL);
159 SDEI_EXPLICIT_EVENT(2000, SDEI_MAPF_CRITICAL);
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100160 };
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
174Configuration within Exception Handling Framework
175-------------------------------------------------
176
177The SDEI dispatcher functions alongside the Exception Handling Framework. This
178means that the platform must assign priorities to both Normal and Critical SDEI
179interrupts 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 Beesleyf8640672019-04-12 14:19:42 +0100191See also :ref:`porting_guide_sdei_requirements`.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100192
193Determining client EL
194---------------------
195
196The SDEI specification requires that the *physical* SDEI client executes in the
197highest Non-secure EL implemented on the system. This means that the dispatcher
198will 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
206See the function ``sdei_client_el()`` in ``sdei_private.h``.
207
Madhukar Pappireddy86350ae2020-07-29 09:37:25 -0500208.. _explicit-dispatch-of-events:
209
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100210Explicit dispatch of events
211---------------------------
212
213Typically, an SDEI event dispatch is caused by the PE receiving interrupts that
214are bound to an SDEI event. However, there are cases where the Secure world
215requires dispatch of an SDEI event as a direct or indirect result of a past
Antonio Nino Diaz56b68ad2019-02-28 13:35:21 +0000216activity, such as receiving a Secure interrupt or an exception.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100217
218The SDEI dispatcher implementation provides ``sdei_dispatch_event()`` API for
219this purpose. The API has the following signature:
220
Paul Beesley493e3492019-03-13 15:11:04 +0000221.. code:: c
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100222
Jeenu Viswambharan8b7e6bc2018-02-16 12:07:48 +0000223 int sdei_dispatch_event(int ev_num);
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100224
Jeenu Viswambharan8b7e6bc2018-02-16 12:07:48 +0000225The parameter ``ev_num`` is the event number to dispatch. The API returns ``0``
226on success, or ``-1`` on failure.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100227
228The following figure depicts a scenario involving explicit dispatch of SDEI
229event. A commentary is provided below:
230
Paul Beesley8c178b52019-07-12 11:56:58 +0100231.. uml:: ../resources/diagrams/plantuml/sdei_explicit_dispatch.puml
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100232
233As part of initialisation, the SDEI client registers a handler for a platform
234event [1], enables the event [3], and unmasks the current PE [5]. Note that,
235unlike in `general SDEI dispatch`_, this doesn't involve interrupt binding, as
236bound or dynamic events can't be explicitly dispatched (see the section below).
237
238At a later point in time, a critical event [#critical-event]_ is trapped into
Jeenu Viswambharan8b7e6bc2018-02-16 12:07:48 +0000239EL3 [7]. EL3 performs a first-level triage of the event, and a RAS component
240assumes further handling [8]. The dispatch completes, but intends to involve
241Non-secure world in further handling, and therefore decides to explicitly
242dispatch an event [10] (which the client had already registered for [1]). The
243rest of the sequence is similar to that in the `general SDEI dispatch`_: the
244requested event is dispatched to the client (assuming all the conditions are
245met), and when the handler completes, the preempted execution resumes.
Jeenu Viswambharan9a62fd12017-11-16 12:34:15 +0000246
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100247Conditions for event dispatch
248~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
249
250All of the following requirements must be met for the API to return ``0`` and
251event 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 Viswambharan34392302018-01-17 12:30:11 +0000258- The event must be declared using the ``SDEI_EXPLICIT_EVENT()`` macro
259 described above.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100260
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
277Further, the caller should be aware of the following assumptions made by the
278dispatcher:
279
Jeenu Viswambharan8b7e6bc2018-02-16 12:07:48 +0000280- The caller of the API is a component running in EL3; for example, a RAS
281 driver.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100282
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 Viswambharan8b7e6bc2018-02-16 12:07:48 +0000288- The caller must be prepared for the SDEI dispatcher to restore the Non-secure
289 context, and mark that the active context.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100290
Jeenu Viswambharan8b7e6bc2018-02-16 12:07:48 +0000291- 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 Viswambharandb5e12e2017-10-18 14:35:20 +0100293
Jeenu Viswambharan8b7e6bc2018-02-16 12:07:48 +0000294- The caller must be prepared for this API to return failure and handle
295 accordingly.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100296
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100297Porting requirements
298--------------------
299
Paul Beesleyf8640672019-04-12 14:19:42 +0100300The porting requirements of the SDEI dispatcher are outlined in the
301:ref:`Porting Guide <porting_guide_sdei_requirements>`.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100302
303Note on writing SDEI event handlers
304-----------------------------------
305
306*This section pertains to SDEI event handlers in general, not just when using
Dan Handley610e7e12018-03-01 18:44:00 +0000307the TF-A SDEI dispatcher.*
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100308
309The SDEI specification requires that event handlers preserve the contents of all
310registers except ``x0`` to ``x17``. This has significance if event handler is
311written in C: compilers typically adjust the stack frame at the beginning and
312end of C functions. For example, AArch64 GCC typically produces the following
313function 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
330The register ``x29`` is used as frame pointer in the prologue. Because neither a
331valid ``SDEI_EVENT_COMPLETE`` nor ``SDEI_EVENT_COMPLETE_AND_RESUME`` calls
332return to the handler, the epilogue never gets executed, and registers ``x29``
333and ``x30`` (in the case above) are inadvertently corrupted. This violates the
334SDEI specification, and the normal execution thereafter will result in
335unexpected behaviour.
336
337To work this around, it's advised that the top-level event handlers are
338implemented 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 Beesleyf8640672019-04-12 14:19:42 +0100355--------------
356
Manish Pandeyb0740212024-01-11 16:06:29 +0000357Security Considerations
358-----------------------
359
360SDEI introduces concept of providing software based non-maskable interrupts to
361Hypervisor/OS. In doing so, it modifies the priority scheme defined by Interrupt
362controllers and relies on Non-Secure clients, Hypervisor or OS, to create/manage
363high priority events.
364
365Considering a Non-secure client is involved in SDEI state management, there exists
366some security considerations which needs to be taken care of in both client and EL3
367when using SDEI. Few of them are mentioned below.
368
369Bound events
370~~~~~~~~~~~~
371
372A bound event is an SDEI event that corresponds to a client interrupt.
373The binding of event is done using ``SDEI_INTERRUPT_BIND`` SMC call to associate
374an SDEI event with a client interrupt. There is a possibility that a rogue
375client can request an invalid interrupt to be bound. This may potentially
376cause out-of-bound memory read.
377
378Even though TF-A implementation has checks to ensure that interrupt ID passed
379by client is architecturally valid, Non-secure client should also ensure the
380validity of interrupts.
381
382Recurring events
383~~~~~~~~~~~~~~~~
384
385For a given event source, if the events are generated continuously, then NS client
386may be unusable. To mitigate against this, the Non-secure client must have
387mechanism in place to remove such interrupt source from the system.
388
389One of the examples is a memory region which continuously generates RAS errors.
390This may result in unusable Non-secure client.
391
392Dispatched events
393~~~~~~~~~~~~~~~~~
394
395For a dispatched event, it is the client's responsibility to ensure that the
396handling finishes in finite time and notify the dispatcher through
397``SDEI_EVENT_COMPLETE`` or ``SDEI_EVENT_COMPLETE_AND_RESUME``. If the client
398fails to complete the event handling, it might result in ``UNPREDICTABLE`` behavior
399in the client and potentially end up in unusable PE.
400
401*Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.*
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100402
Paul Beesleyf8640672019-04-12 14:19:42 +0100403.. 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 Viswambharandb5e12e2017-10-18 14:35:20 +0100411
412.. _SDEI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
John Tsichritzise14a9bb2019-05-28 12:45:06 +0100413.. _Software Delegated Exception Interface: `SDEI specification`_