Merge pull request #1161 from jeenu-arm/sdei-fixes

SDEI fixes
This commit is contained in:
davidcunado-arm 2017-11-22 13:57:03 +00:00 committed by GitHub
commit a2d60b20ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 27 additions and 20 deletions

View File

@ -9,7 +9,7 @@
autonumber "<b>[#]</b>"
participant "SDEI client" as EL2
participant EL3
participant SEL1
participant "Secure Partition" as SP
activate EL2
EL2->EL3: **SDEI_EVENT_REGISTER**(ev, handler, ...)
@ -24,11 +24,11 @@ EL3->EL2: 1
EL3<--]: **CRITICAL EVENT**
activate EL3 #red
note over EL3: Critical event triage
EL3->SEL1: dispatch
activate SEL1 #salmon
note over SEL1: Critical event handling
SEL1->EL3: done
deactivate SEL1
EL3->SP: dispatch
activate SP #salmon
note over SP: Critical event handling
SP->EL3: done
deactivate SP
EL3-->EL3: sdei_dispatch_event(ev)
note over EL3: Prepare SDEI dispatch
EL3->EL2: dispatch

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -232,13 +232,20 @@ bound or dynamic events can't be explicitly dispatched (see the section below).
At a later point in time, a critical event [#critical-event]_ is trapped into
EL3 [7]. EL3 performs a first-level triage of the event, and decides to dispatch
to Secure EL1 for further handling [8]. The dispatch completes, but intends to
involve Non-secure world in further handling, and therefore decides to
explicitly dispatch an event [10] (which the client had already registered for
[1]). The rest of the sequence is similar to that in the `general SDEI
dispatch`_: the requested event is dispatched to the client (assuming all the
conditions are met), and when the handler completes, the preempted execution
resumes.
to a Secure Partition [#secpart]_ for further handling [8]. The dispatch
completes, but intends to involve Non-secure world in further handling, and
therefore decides to explicitly dispatch an event [10] (which the client had
already registered for [1]). The rest of the sequence is similar to that in the
`general SDEI dispatch`_: the requested event is dispatched to the client
(assuming all the conditions are met), and when the handler completes, the
preempted execution resumes.
.. [#critical-event] Examples of critical event are *SError*, *Synchronous
External Abort*, *Fault Handling interrupt*, or *Error
Recovery interrupt* from one of RAS nodes in the system.
.. [#secpart] Dispatching to Secure Partition involves *Secure Partition
Manager*, which isn't depicted in the sequence.
Conditions for event dispatch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -295,10 +302,6 @@ dispatcher:
context is resumed (as indicated by the ``preempted_sec_state`` parameter of
the API).
.. [#critical-event] Examples of critical event are *SError*, *Synchronous
External Abort*, *Fault Handling interrupt*, or *Error
Recovery interrupt* from one of RAS nodes in the system.
Porting requirements
--------------------

View File

@ -154,7 +154,7 @@ typedef struct sdei_ev_map {
int32_t ev_num; /* Event number */
unsigned int intr; /* Physical interrupt number for a bound map */
unsigned int map_flags; /* Mapping flags, see SDEI_MAPF_* */
unsigned int reg_count; /* Registration count */
int reg_count; /* Registration count */
spinlock_t lock; /* Per-event lock */
} sdei_ev_map_t;

View File

@ -475,8 +475,10 @@ int sdei_dispatch_event(int ev_num, unsigned int preempted_sec_state)
sdei_cpu_state_t *state;
/* Validate preempted security state */
if ((preempted_sec_state != SECURE) || (preempted_sec_state != NON_SECURE))
if ((preempted_sec_state != SECURE) &&
(preempted_sec_state != NON_SECURE)) {
return -1;
}
/* Can't dispatch if events are masked on this PE */
state = sdei_get_this_pe_state();

View File

@ -120,6 +120,7 @@ void sdei_class_init(sdei_class_t class)
/* Platform events are always bound, so set the bound flag */
if (is_map_dynamic(map)) {
assert(map->intr == SDEI_DYN_IRQ);
assert(is_event_normal(map));
num_dyn_shrd_slots++;
} else {
/* Shared mappings must be bound to shared interrupt */
@ -171,6 +172,7 @@ void sdei_class_init(sdei_class_t class)
if (map->ev_num != SDEI_EVENT_0) {
if (is_map_dynamic(map)) {
assert(map->intr == SDEI_DYN_IRQ);
assert(is_event_normal(map));
num_dyn_priv_slots++;
} else {
/*