arm-trusted-firmware/services/std_svc/spm_mm/aarch64/spm_mm_shim_exceptions.S

129 lines
3.1 KiB
ArmAsm
Raw Normal View History

/*
Prevent speculative execution past ERET Even though ERET always causes a jump to another address, aarch64 CPUs speculatively execute following instructions as if the ERET instruction was not a jump instruction. The speculative execution does not cross privilege-levels (to the jump target as one would expect), but it continues on the kernel privilege level as if the ERET instruction did not change the control flow - thus execution anything that is accidentally linked after the ERET instruction. Later, the results of this speculative execution are always architecturally discarded, however they can leak data using microarchitectural side channels. This speculative execution is very reliable (seems to be unconditional) and it manages to complete even relatively performance-heavy operations (e.g. multiple dependent fetches from uncached memory). This was fixed in Linux, FreeBSD, OpenBSD and Optee OS: https://github.com/torvalds/linux/commit/679db70801da9fda91d26caf13bf5b5ccc74e8e8 https://github.com/freebsd/freebsd/commit/29fb48ace4186a41c409fde52bcf4216e9e50b61 https://github.com/openbsd/src/commit/3a08873ece1cb28ace89fd65e8f3c1375cc98de2 https://github.com/OP-TEE/optee_os/commit/abfd092aa19f9c0251e3d5551e2d68a9ebcfec8a It is demonstrated in a SafeSide example: https://github.com/google/safeside/blob/master/demos/eret_hvc_smc_wrapper.cc https://github.com/google/safeside/blob/master/kernel_modules/kmod_eret_hvc_smc/eret_hvc_smc_module.c Signed-off-by: Anthony Steinhauser <asteinhauser@google.com> Change-Id: Iead39b0b9fb4b8d8b5609daaa8be81497ba63a0f
2020-01-07 23:44:06 +00:00
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <common/bl_common.h>
#include <context.h>
/* -----------------------------------------------------------------------------
* Very simple stackless exception handlers used by the spm shim layer.
* -----------------------------------------------------------------------------
*/
.globl spm_shim_exceptions_ptr
vector_base spm_shim_exceptions_ptr, .spm_shim_exceptions
/* -----------------------------------------------------
* Current EL with SP0 : 0x0 - 0x200
* -----------------------------------------------------
*/
vector_entry SynchronousExceptionSP0, .spm_shim_exceptions
b .
end_vector_entry SynchronousExceptionSP0
vector_entry IrqSP0, .spm_shim_exceptions
b .
end_vector_entry IrqSP0
vector_entry FiqSP0, .spm_shim_exceptions
b .
end_vector_entry FiqSP0
vector_entry SErrorSP0, .spm_shim_exceptions
b .
end_vector_entry SErrorSP0
/* -----------------------------------------------------
* Current EL with SPx: 0x200 - 0x400
* -----------------------------------------------------
*/
vector_entry SynchronousExceptionSPx, .spm_shim_exceptions
b .
end_vector_entry SynchronousExceptionSPx
vector_entry IrqSPx, .spm_shim_exceptions
b .
end_vector_entry IrqSPx
vector_entry FiqSPx, .spm_shim_exceptions
b .
end_vector_entry FiqSPx
vector_entry SErrorSPx, .spm_shim_exceptions
b .
end_vector_entry SErrorSPx
/* -----------------------------------------------------
* Lower EL using AArch64 : 0x400 - 0x600. No exceptions
* are handled since secure_partition does not implement
* a lower EL
* -----------------------------------------------------
*/
vector_entry SynchronousExceptionA64, .spm_shim_exceptions
msr tpidr_el1, x30
mrs x30, esr_el1
ubfx x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
cmp x30, #EC_AARCH64_SVC
b.eq do_smc
cmp x30, #EC_AARCH32_SVC
b.eq do_smc
cmp x30, #EC_AARCH64_SYS
b.eq handle_sys_trap
/* Fail in all the other cases */
b panic
/* ---------------------------------------------
* Tell SPM that we are done initialising
* ---------------------------------------------
*/
do_smc:
mrs x30, tpidr_el1
smc #0
Prevent speculative execution past ERET Even though ERET always causes a jump to another address, aarch64 CPUs speculatively execute following instructions as if the ERET instruction was not a jump instruction. The speculative execution does not cross privilege-levels (to the jump target as one would expect), but it continues on the kernel privilege level as if the ERET instruction did not change the control flow - thus execution anything that is accidentally linked after the ERET instruction. Later, the results of this speculative execution are always architecturally discarded, however they can leak data using microarchitectural side channels. This speculative execution is very reliable (seems to be unconditional) and it manages to complete even relatively performance-heavy operations (e.g. multiple dependent fetches from uncached memory). This was fixed in Linux, FreeBSD, OpenBSD and Optee OS: https://github.com/torvalds/linux/commit/679db70801da9fda91d26caf13bf5b5ccc74e8e8 https://github.com/freebsd/freebsd/commit/29fb48ace4186a41c409fde52bcf4216e9e50b61 https://github.com/openbsd/src/commit/3a08873ece1cb28ace89fd65e8f3c1375cc98de2 https://github.com/OP-TEE/optee_os/commit/abfd092aa19f9c0251e3d5551e2d68a9ebcfec8a It is demonstrated in a SafeSide example: https://github.com/google/safeside/blob/master/demos/eret_hvc_smc_wrapper.cc https://github.com/google/safeside/blob/master/kernel_modules/kmod_eret_hvc_smc/eret_hvc_smc_module.c Signed-off-by: Anthony Steinhauser <asteinhauser@google.com> Change-Id: Iead39b0b9fb4b8d8b5609daaa8be81497ba63a0f
2020-01-07 23:44:06 +00:00
exception_return
/* AArch64 system instructions trap are handled as a panic for now */
handle_sys_trap:
panic:
b panic
end_vector_entry SynchronousExceptionA64
vector_entry IrqA64, .spm_shim_exceptions
b .
end_vector_entry IrqA64
vector_entry FiqA64, .spm_shim_exceptions
b .
end_vector_entry FiqA64
vector_entry SErrorA64, .spm_shim_exceptions
b .
end_vector_entry SErrorA64
/* -----------------------------------------------------
* Lower EL using AArch32 : 0x600 - 0x800
* -----------------------------------------------------
*/
vector_entry SynchronousExceptionA32, .spm_shim_exceptions
b .
end_vector_entry SynchronousExceptionA32
vector_entry IrqA32, .spm_shim_exceptions
b .
end_vector_entry IrqA32
vector_entry FiqA32, .spm_shim_exceptions
b .
end_vector_entry FiqA32
vector_entry SErrorA32, .spm_shim_exceptions
b .
end_vector_entry SErrorA32