aboutsummaryrefslogtreecommitdiff
path: root/services/std_svc/sdei/sdei_intr_mgmt.c
diff options
context:
space:
mode:
authorDimitris Papastamos <dimitris.papastamos@arm.com>2018-06-07 11:29:15 +0100
committerDimitris Papastamos <dimitris.papastamos@arm.com>2018-06-08 11:46:31 +0100
commit6f03bc7753a22485ad2b531a11e96756147facbe (patch)
treee411a969ab2cfcabc579b434419a30cf5ada66c0 /services/std_svc/sdei/sdei_intr_mgmt.c
parentd6b798097e23bc98814ced8406f4dc63df4078c5 (diff)
downloadtrusted-firmware-a-6f03bc7753a22485ad2b531a11e96756147facbe.tar.gz
SDEI: Ensure SDEI handler executes with CVE-2018-3639 mitigation enabled
When dynamic mitigation is used, the SDEI handler is required to execute with the mitigation enabled by default, regardless of the mitigation state for lower ELs. This means that if the kernel or hypervisor explicitly disables the mitigation and then later when the event is dispatched, the dispatcher will remember the mitigation state for the lower ELs but force the mitigation to be on during the SDEI handler execution. When the SDEI handler returns, it will restore the mitigation state. This behaviour is described in "Firmware interfaces for mitigating cache speculation vulnerabilities System Software on Arm Systems"[0]. [0] https://developer.arm.com/cache-speculation-vulnerability-firmware-specification Change-Id: I8dd60b736be0aa9e832b0f92d67a401fdeb417f4 Signed-off-by: Dimitris Papastamos <dimitris.papastamos@arm.com>
Diffstat (limited to 'services/std_svc/sdei/sdei_intr_mgmt.c')
-rw-r--r--services/std_svc/sdei/sdei_intr_mgmt.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c
index 2717ea43bd..c0bd9de6bf 100644
--- a/services/std_svc/sdei/sdei_intr_mgmt.c
+++ b/services/std_svc/sdei/sdei_intr_mgmt.c
@@ -39,6 +39,11 @@ typedef struct sdei_dispatch_context {
/* Exception state registers */
uint64_t elr_el3;
uint64_t spsr_el3;
+
+#if DYNAMIC_WORKAROUND_CVE_2018_3639
+ /* CVE-2018-3639 mitigation state */
+ uint64_t disable_cve_2018_3639;
+#endif
} sdei_dispatch_context_t;
/* Per-CPU SDEI state data */
@@ -170,6 +175,18 @@ static void save_event_ctx(sdei_ev_map_t *map, void *tgt_ctx, int sec_state,
memcpy(disp_ctx->x, tgt_gpregs, sizeof(disp_ctx->x));
disp_ctx->spsr_el3 = read_ctx_reg(tgt_el3, CTX_SPSR_EL3);
disp_ctx->elr_el3 = read_ctx_reg(tgt_el3, CTX_ELR_EL3);
+
+#if DYNAMIC_WORKAROUND_CVE_2018_3639
+ cve_2018_3639_t *tgt_cve_2018_3639;
+ tgt_cve_2018_3639 = get_cve_2018_3639_ctx(tgt_ctx);
+
+ /* Save CVE-2018-3639 mitigation state */
+ disp_ctx->disable_cve_2018_3639 = read_ctx_reg(tgt_cve_2018_3639,
+ CTX_CVE_2018_3639_DISABLE);
+
+ /* Force SDEI handler to execute with mitigation enabled by default */
+ write_ctx_reg(tgt_cve_2018_3639, CTX_CVE_2018_3639_DISABLE, 0);
+#endif
}
static void restore_event_ctx(sdei_dispatch_context_t *disp_ctx, void *tgt_ctx)
@@ -188,6 +205,15 @@ static void restore_event_ctx(sdei_dispatch_context_t *disp_ctx, void *tgt_ctx)
memcpy(tgt_gpregs, disp_ctx->x, sizeof(disp_ctx->x));
write_ctx_reg(tgt_el3, CTX_SPSR_EL3, disp_ctx->spsr_el3);
write_ctx_reg(tgt_el3, CTX_ELR_EL3, disp_ctx->elr_el3);
+
+#if DYNAMIC_WORKAROUND_CVE_2018_3639
+ cve_2018_3639_t *tgt_cve_2018_3639;
+ tgt_cve_2018_3639 = get_cve_2018_3639_ctx(tgt_ctx);
+
+ /* Restore CVE-2018-3639 mitigation state */
+ write_ctx_reg(tgt_cve_2018_3639, CTX_CVE_2018_3639_DISABLE,
+ disp_ctx->disable_cve_2018_3639);
+#endif
}
static void save_secure_context(void)