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>" autonumber "<b>[#]</b>"
participant "SDEI client" as EL2 participant "SDEI client" as EL2
participant EL3 participant EL3
participant SEL1 participant "Secure Partition" as SP
activate EL2 activate EL2
EL2->EL3: **SDEI_EVENT_REGISTER**(ev, handler, ...) EL2->EL3: **SDEI_EVENT_REGISTER**(ev, handler, ...)
@ -24,11 +24,11 @@ EL3->EL2: 1
EL3<--]: **CRITICAL EVENT** EL3<--]: **CRITICAL EVENT**
activate EL3 #red activate EL3 #red
note over EL3: Critical event triage note over EL3: Critical event triage
EL3->SEL1: dispatch EL3->SP: dispatch
activate SEL1 #salmon activate SP #salmon
note over SEL1: Critical event handling note over SP: Critical event handling
SEL1->EL3: done SP->EL3: done
deactivate SEL1 deactivate SP
EL3-->EL3: sdei_dispatch_event(ev) EL3-->EL3: sdei_dispatch_event(ev)
note over EL3: Prepare SDEI dispatch note over EL3: Prepare SDEI dispatch
EL3->EL2: 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 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 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 to a Secure Partition [#secpart]_ for further handling [8]. The dispatch
involve Non-secure world in further handling, and therefore decides to completes, but intends to involve Non-secure world in further handling, and
explicitly dispatch an event [10] (which the client had already registered for therefore decides to explicitly dispatch an event [10] (which the client had
[1]). The rest of the sequence is similar to that in the `general SDEI already registered for [1]). The rest of the sequence is similar to that in the
dispatch`_: the requested event is dispatched to the client (assuming all the `general SDEI dispatch`_: the requested event is dispatched to the client
conditions are met), and when the handler completes, the preempted execution (assuming all the conditions are met), and when the handler completes, the
resumes. 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 Conditions for event dispatch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -295,10 +302,6 @@ dispatcher:
context is resumed (as indicated by the ``preempted_sec_state`` parameter of context is resumed (as indicated by the ``preempted_sec_state`` parameter of
the API). 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 Porting requirements
-------------------- --------------------

View File

@ -154,7 +154,7 @@ typedef struct sdei_ev_map {
int32_t ev_num; /* Event number */ int32_t ev_num; /* Event number */
unsigned int intr; /* Physical interrupt number for a bound map */ unsigned int intr; /* Physical interrupt number for a bound map */
unsigned int map_flags; /* Mapping flags, see SDEI_MAPF_* */ 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 */ spinlock_t lock; /* Per-event lock */
} sdei_ev_map_t; } 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; sdei_cpu_state_t *state;
/* Validate preempted security 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; return -1;
}
/* Can't dispatch if events are masked on this PE */ /* Can't dispatch if events are masked on this PE */
state = sdei_get_this_pe_state(); 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 */ /* Platform events are always bound, so set the bound flag */
if (is_map_dynamic(map)) { if (is_map_dynamic(map)) {
assert(map->intr == SDEI_DYN_IRQ); assert(map->intr == SDEI_DYN_IRQ);
assert(is_event_normal(map));
num_dyn_shrd_slots++; num_dyn_shrd_slots++;
} else { } else {
/* Shared mappings must be bound to shared interrupt */ /* 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 (map->ev_num != SDEI_EVENT_0) {
if (is_map_dynamic(map)) { if (is_map_dynamic(map)) {
assert(map->intr == SDEI_DYN_IRQ); assert(map->intr == SDEI_DYN_IRQ);
assert(is_event_normal(map));
num_dyn_priv_slots++; num_dyn_priv_slots++;
} else { } else {
/* /*