summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDimitris Papastamos <dimitris.papastamos@arm.com>2017-11-30 14:53:53 +0000
committerDimitris Papastamos <dimitris.papastamos@arm.com>2018-01-11 10:26:15 +0000
commitf62ad322695d16178db464dc062fe0af592c6780 (patch)
treef814211090c6e75550c908a47a45fcad022a186f /lib
parent08e06be81946de2701429e72840bb76ee3f9a48e (diff)
Workaround for CVE-2017-5715 on Cortex A57 and A72
Invalidate the Branch Target Buffer (BTB) on entry to EL3 by disabling and enabling the MMU. To achieve this without performing any branch instruction, a per-cpu vbar is installed which executes the workaround and then branches off to the corresponding vector entry in the main vector table. A side effect of this change is that the main vbar is configured before any reset handling. This is to allow the per-cpu reset function to override the vbar setting. This workaround is enabled by default on the affected CPUs. Change-Id: I97788d38463a5840a410e3cea85ed297a1678265 Signed-off-by: Dimitris Papastamos <dimitris.papastamos@arm.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/cpus/aarch64/cortex_a57.S5
-rw-r--r--lib/cpus/aarch64/cortex_a72.S6
-rw-r--r--lib/cpus/aarch64/workaround_cve_2017_5715_mmu.S114
-rw-r--r--lib/cpus/cpu-ops.mk5
4 files changed, 130 insertions, 0 deletions
diff --git a/lib/cpus/aarch64/cortex_a57.S b/lib/cpus/aarch64/cortex_a57.S
index a720e984..683be47e 100644
--- a/lib/cpus/aarch64/cortex_a57.S
+++ b/lib/cpus/aarch64/cortex_a57.S
@@ -383,6 +383,11 @@ func cortex_a57_reset_func
bl errata_a57_859972_wa
#endif
+#if IMAGE_BL31 && WORKAROUND_CVE_2017_5715
+ adr x0, workaround_mmu_runtime_exceptions
+ msr vbar_el3, x0
+#endif
+
/* ---------------------------------------------
* Enable the SMP bit.
* ---------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a72.S b/lib/cpus/aarch64/cortex_a72.S
index b0341256..93821b74 100644
--- a/lib/cpus/aarch64/cortex_a72.S
+++ b/lib/cpus/aarch64/cortex_a72.S
@@ -110,6 +110,12 @@ func cortex_a72_reset_func
mov x0, x18
bl errata_a72_859971_wa
#endif
+
+#if IMAGE_BL31 && WORKAROUND_CVE_2017_5715
+ adr x0, workaround_mmu_runtime_exceptions
+ msr vbar_el3, x0
+#endif
+
/* ---------------------------------------------
* Enable the SMP bit.
* ---------------------------------------------
diff --git a/lib/cpus/aarch64/workaround_cve_2017_5715_mmu.S b/lib/cpus/aarch64/workaround_cve_2017_5715_mmu.S
new file mode 100644
index 00000000..f4781484
--- /dev/null
+++ b/lib/cpus/aarch64/workaround_cve_2017_5715_mmu.S
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <context.h>
+
+ .globl workaround_mmu_runtime_exceptions
+
+vector_base workaround_mmu_runtime_exceptions
+
+ .macro apply_workaround
+ stp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
+ mrs x0, sctlr_el3
+ /* Disable MMU */
+ bic x1, x0, #SCTLR_M_BIT
+ msr sctlr_el3, x1
+ isb
+ /* Restore MMU config */
+ msr sctlr_el3, x0
+ isb
+ ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
+ .endm
+
+ /* ---------------------------------------------------------------------
+ * Current EL with SP_EL0 : 0x0 - 0x200
+ * ---------------------------------------------------------------------
+ */
+vector_entry workaround_mmu_sync_exception_sp_el0
+ b sync_exception_sp_el0
+ check_vector_size workaround_mmu_sync_exception_sp_el0
+
+vector_entry workaround_mmu_irq_sp_el0
+ b irq_sp_el0
+ check_vector_size workaround_mmu_irq_sp_el0
+
+vector_entry workaround_mmu_fiq_sp_el0
+ b fiq_sp_el0
+ check_vector_size workaround_mmu_fiq_sp_el0
+
+vector_entry workaround_mmu_serror_sp_el0
+ b serror_sp_el0
+ check_vector_size workaround_mmu_serror_sp_el0
+
+ /* ---------------------------------------------------------------------
+ * Current EL with SP_ELx: 0x200 - 0x400
+ * ---------------------------------------------------------------------
+ */
+vector_entry workaround_mmu_sync_exception_sp_elx
+ b sync_exception_sp_elx
+ check_vector_size workaround_mmu_sync_exception_sp_elx
+
+vector_entry workaround_mmu_irq_sp_elx
+ b irq_sp_elx
+ check_vector_size workaround_mmu_irq_sp_elx
+
+vector_entry workaround_mmu_fiq_sp_elx
+ b fiq_sp_elx
+ check_vector_size workaround_mmu_fiq_sp_elx
+
+vector_entry workaround_mmu_serror_sp_elx
+ b serror_sp_elx
+ check_vector_size workaround_mmu_serror_sp_elx
+
+ /* ---------------------------------------------------------------------
+ * Lower EL using AArch64 : 0x400 - 0x600
+ * ---------------------------------------------------------------------
+ */
+vector_entry workaround_mmu_sync_exception_aarch64
+ apply_workaround
+ b sync_exception_aarch64
+ check_vector_size workaround_mmu_sync_exception_aarch64
+
+vector_entry workaround_mmu_irq_aarch64
+ apply_workaround
+ b irq_aarch64
+ check_vector_size workaround_mmu_irq_aarch64
+
+vector_entry workaround_mmu_fiq_aarch64
+ apply_workaround
+ b fiq_aarch64
+ check_vector_size workaround_mmu_fiq_aarch64
+
+vector_entry workaround_mmu_serror_aarch64
+ apply_workaround
+ b serror_aarch64
+ check_vector_size workaround_mmu_serror_aarch64
+
+ /* ---------------------------------------------------------------------
+ * Lower EL using AArch32 : 0x600 - 0x800
+ * ---------------------------------------------------------------------
+ */
+vector_entry workaround_mmu_sync_exception_aarch32
+ apply_workaround
+ b sync_exception_aarch32
+ check_vector_size workaround_mmu_sync_exception_aarch32
+
+vector_entry workaround_mmu_irq_aarch32
+ apply_workaround
+ b irq_aarch32
+ check_vector_size workaround_mmu_irq_aarch32
+
+vector_entry workaround_mmu_fiq_aarch32
+ apply_workaround
+ b fiq_aarch32
+ check_vector_size workaround_mmu_fiq_aarch32
+
+vector_entry workaround_mmu_serror_aarch32
+ apply_workaround
+ b serror_aarch32
+ check_vector_size workaround_mmu_serror_aarch32
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 31adfb42..3ba8c1fc 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -16,6 +16,8 @@ A53_DISABLE_NON_TEMPORAL_HINT ?=1
# It is enabled by default.
A57_DISABLE_NON_TEMPORAL_HINT ?=1
+WORKAROUND_CVE_2017_5715 ?=1
+
# Process SKIP_A57_L1_FLUSH_PWR_DWN flag
$(eval $(call assert_boolean,SKIP_A57_L1_FLUSH_PWR_DWN))
$(eval $(call add_define,SKIP_A57_L1_FLUSH_PWR_DWN))
@@ -28,6 +30,9 @@ $(eval $(call add_define,A53_DISABLE_NON_TEMPORAL_HINT))
$(eval $(call assert_boolean,A57_DISABLE_NON_TEMPORAL_HINT))
$(eval $(call add_define,A57_DISABLE_NON_TEMPORAL_HINT))
+# Process WORKAROUND_CVE_2017_5715 flag
+$(eval $(call assert_boolean,WORKAROUND_CVE_2017_5715))
+$(eval $(call add_define,WORKAROUND_CVE_2017_5715))
# CPU Errata Build flags.
# These should be enabled by the platform if the erratum workaround needs to be