diff options
author | Dimitris Papastamos <dimitris.papastamos@arm.com> | 2017-11-30 14:53:53 +0000 |
---|---|---|
committer | Dimitris Papastamos <dimitris.papastamos@arm.com> | 2018-01-11 10:26:15 +0000 |
commit | f62ad322695d16178db464dc062fe0af592c6780 (patch) | |
tree | f814211090c6e75550c908a47a45fcad022a186f /lib | |
parent | 08e06be81946de2701429e72840bb76ee3f9a48e (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.S | 5 | ||||
-rw-r--r-- | lib/cpus/aarch64/cortex_a72.S | 6 | ||||
-rw-r--r-- | lib/cpus/aarch64/workaround_cve_2017_5715_mmu.S | 114 | ||||
-rw-r--r-- | lib/cpus/cpu-ops.mk | 5 |
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 |