Supervisor Call instruction (SVC) is used by the Arm Standalone MM environment to request services from the privileged software (such as ARM Trusted Firmware running in EL3) and also return back to the non-secure caller via EL3. Some Arm CPUs speculatively executes the instructions after the SVC instruction without crossing the privilege level (S-EL0). Although the results of this execution are architecturally discarded, adversary running on the non-secure side can manipulate the contents of the general purpose registers to leak the secure work memory through spectre like micro-architectural side channel attacks. This behavior is demonstrated by the SafeSide project [1] and [2]. Add barrier instructions after SVC to prevent speculative execution to mitigate such attacks. [1]: https://github.com/google/safeside/blob/master/demos/eret_hvc_smc_wrapper.cc [2]: https://github.com/google/safeside/blob/master/kernel_modules/kmod_eret_hvc_smc/eret_hvc_smc_module.c Signed-off-by: Vijayenthiran Subramaniam <vijayenthiran.subramaniam@arm.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
44 lines
1.0 KiB
ArmAsm
44 lines
1.0 KiB
ArmAsm
//
|
|
// Copyright (c) 2012 - 2020, ARM Limited. All rights reserved.
|
|
//
|
|
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
//
|
|
//
|
|
|
|
.text
|
|
.align 3
|
|
|
|
GCC_ASM_EXPORT(ArmCallSvc)
|
|
|
|
ASM_PFX(ArmCallSvc):
|
|
// Push frame pointer and return address on the stack
|
|
stp x29, x30, [sp, #-32]!
|
|
mov x29, sp
|
|
|
|
// Push x0 on the stack - The stack must always be quad-word aligned
|
|
str x0, [sp, #16]
|
|
|
|
// Load the SVC arguments values into the appropriate registers
|
|
ldp x6, x7, [x0, #48]
|
|
ldp x4, x5, [x0, #32]
|
|
ldp x2, x3, [x0, #16]
|
|
ldp x0, x1, [x0, #0]
|
|
|
|
svc #0
|
|
// Prevent speculative execution beyond svc instruction
|
|
dsb nsh
|
|
isb
|
|
|
|
// Pop the ARM_SVC_ARGS structure address from the stack into x9
|
|
ldr x9, [sp, #16]
|
|
|
|
// Store the SVC returned values into the ARM_SVC_ARGS structure.
|
|
// A SVC call can return up to 4 values - we do not need to store back x4-x7.
|
|
stp x0, x1, [x9, #0]
|
|
stp x2, x3, [x9, #16]
|
|
|
|
mov x0, x9
|
|
|
|
ldp x29, x30, [sp], #32
|
|
ret
|