diff options
author | Jeenu Viswambharan <jeenu.viswambharan@arm.com> | 2017-10-04 12:21:34 +0100 |
---|---|---|
committer | Jeenu Viswambharan <jeenu.viswambharan@arm.com> | 2017-11-13 07:49:30 +0000 |
commit | 3d732e23e71343f2ba18d456c8f2163015209768 (patch) | |
tree | 8cfd70e85966e42b56b8b90a5631a2b55f038bbd /include/bl31 | |
parent | 21b818c05fa4ec8cec468aad690267c5be930ccd (diff) | |
download | arm-trusted-firmware-3d732e23e71343f2ba18d456c8f2163015209768.tar.gz |
BL31: Program Priority Mask for SMC handling
On GICv3 systems, as a side effect of adding provision to handle EL3
interrupts (unconditionally routing FIQs to EL3), pending Non-secure
interrupts (signalled as FIQs) may preempt execution in lower Secure ELs
[1]. This will inadvertently disrupt the semantics of Fast SMC
(previously called Atomic SMC) calls.
To retain semantics of Fast SMCs, the GIC PMR must be programmed to
prevent Non-secure interrupts from preempting Secure execution. To that
effect, two new functions in the Exception Handling Framework subscribe
to events introduced in an earlier commit:
- Upon 'cm_exited_normal_world', the Non-secure PMR is stashed, and
the PMR is programmed to the highest Non-secure interrupt priority.
- Upon 'cm_entering_normal_world', the previously stashed Non-secure
PMR is restored.
The above sequence however prevents Yielding SMCs from being preempted
by Non-secure interrupts as intended. To facilitate this, the public API
exc_allow_ns_preemption() is introduced that programs the PMR to the
original Non-secure PMR value. Another API
exc_is_ns_preemption_allowed() is also introduced to check if
exc_allow_ns_preemption() had been called previously.
API documentation to follow.
[1] On GICv2 systems, this isn't a problem as, unlike GICv3, pending NS
IRQs during Secure execution are signalled as IRQs, which aren't
routed to EL3.
Change-Id: Ief96b162b0067179b1012332cd991ee1b3051dd0
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
Diffstat (limited to 'include/bl31')
-rw-r--r-- | include/bl31/ehf.h | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/include/bl31/ehf.h b/include/bl31/ehf.h index 142b4c0aa..be8c957cc 100644 --- a/include/bl31/ehf.h +++ b/include/bl31/ehf.h @@ -55,6 +55,9 @@ typedef struct { /* Priority mask value before any priority levels were active */ uint8_t init_pri_mask; + + /* Non-secure priority mask value stashed during Secure execution */ + uint8_t ns_pri_mask; } __aligned(sizeof(uint64_t)) pe_exc_data_t; typedef int (*ehf_handler_t)(uint32_t intr_raw, uint32_t flags, void *handle, @@ -79,6 +82,8 @@ void ehf_init(void); void ehf_activate_priority(unsigned int priority); void ehf_deactivate_priority(unsigned int priority); void ehf_register_priority_handler(unsigned int pri, ehf_handler_t handler); +void ehf_allow_ns_preemption(void); +unsigned int ehf_is_ns_preemption_allowed(void); #endif /* __ASSEMBLY__ */ |