diff options
author | Douglas Raillard <douglas.raillard@arm.com> | 2016-11-24 15:43:19 +0000 |
---|---|---|
committer | Douglas Raillard <douglas.raillard@arm.com> | 2016-12-23 10:46:32 +0000 |
commit | 3df6012a3eff73d75d747187d7cfac1fd6d7819f (patch) | |
tree | e46500a3463b4b45b38e5815314aea100634b177 /bl32/tsp | |
parent | 153e5eb8f155ec001027ee28bfc229b67ccceee0 (diff) |
Abort preempted TSP STD SMC after PSCI CPU suspend
Standard SMC requests that are handled in the secure-world by the Secure
Payload can be preempted by interrupts that must be handled in the
normal world. When the TSP is preempted the secure context is stored and
control is passed to the normal world to handle the non-secure
interrupt. Once completed the preempted secure context is restored. When
restoring the preempted context, the dispatcher assumes that the TSP
preempted context is still stored as the SECURE context by the context
management library.
However, PSCI power management operations causes synchronous entry into
TSP. This overwrites the preempted SECURE context in the context
management library. When restoring back the SECURE context, the Secure
Payload crashes because this context is not the preempted context
anymore.
This patch avoids corruption of the preempted SECURE context by aborting
any preempted SMC during PSCI power management calls. The
abort_std_smc_entry hook of the TSP is called when aborting the SMC
request.
It also exposes this feature as a FAST SMC callable from normal world to
abort preempted SMC with FID TSP_FID_ABORT.
Change-Id: I7a70347e9293f47d87b5de20484b4ffefb56b770
Signed-off-by: Douglas Raillard <douglas.raillard@arm.com>
Diffstat (limited to 'bl32/tsp')
-rw-r--r-- | bl32/tsp/aarch64/tsp_entrypoint.S | 28 | ||||
-rw-r--r-- | bl32/tsp/tsp_main.c | 19 |
2 files changed, 46 insertions, 1 deletions
diff --git a/bl32/tsp/aarch64/tsp_entrypoint.S b/bl32/tsp/aarch64/tsp_entrypoint.S index 25385caa..4c296d4a 100644 --- a/bl32/tsp/aarch64/tsp_entrypoint.S +++ b/bl32/tsp/aarch64/tsp_entrypoint.S @@ -180,6 +180,7 @@ func tsp_vector_table b tsp_sel1_intr_entry b tsp_system_off_entry b tsp_system_reset_entry + b tsp_abort_std_smc_entry endfunc tsp_vector_table /*--------------------------------------------- @@ -441,3 +442,30 @@ func tsp_std_smc_entry /* Should never reach here */ no_ret plat_panic_handler endfunc tsp_std_smc_entry + + /*--------------------------------------------------------------------- + * This entrypoint is used by the TSPD to abort a pre-empted Standard + * SMC. It could be on behalf of non-secure world or because a CPU + * suspend/CPU off request needs to abort the preempted SMC. + * -------------------------------------------------------------------- + */ +func tsp_abort_std_smc_entry + + /* + * Exceptions masking is already done by the TSPD when entering this + * hook so there is no need to do it here. + */ + + /* Reset the stack used by the pre-empted SMC */ + bl plat_set_my_stack + + /* + * Allow some cleanup such as releasing locks. + */ + bl tsp_abort_smc_handler + + restore_args_call_smc + + /* Should never reach here */ + bl plat_panic_handler +endfunc tsp_abort_std_smc_entry diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c index d03f7e22..2b365320 100644 --- a/bl32/tsp/tsp_main.c +++ b/bl32/tsp/tsp_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -416,3 +416,20 @@ tsp_args_t *tsp_smc_handler(uint64_t func, 0, 0, 0, 0); } +/******************************************************************************* + * TSP smc abort handler. This function is called when aborting a preemtped + * standard SMC request. It should cleanup all resources owned by the SMC + * handler such as locks or dynamically allocated memory so following SMC + * request are executed in a clean environment. + ******************************************************************************/ +tsp_args_t *tsp_abort_smc_handler(uint64_t func, + uint64_t arg1, + uint64_t arg2, + uint64_t arg3, + uint64_t arg4, + uint64_t arg5, + uint64_t arg6, + uint64_t arg7) +{ + return set_smc_args(TSP_ABORT_DONE, 0, 0, 0, 0, 0, 0, 0); +} |