aboutsummaryrefslogtreecommitdiff
path: root/bl31
diff options
context:
space:
mode:
authorJeenu Viswambharan <jeenu.viswambharan@arm.com>2018-01-22 12:29:12 +0000
committerJeenu Viswambharan <jeenu.viswambharan@arm.com>2018-02-27 13:46:33 +0000
commitaf34cd72ca3b716d8a9800c83b1577e3a39cf41b (patch)
tree49d896aee91e6dae2edbcacae0afc3b3b983394d /bl31
parent5ff6da948710361dec294f4b5106978501531caf (diff)
downloadtrusted-firmware-a-af34cd72ca3b716d8a9800c83b1577e3a39cf41b.tar.gz
EHF: Introduce preempted return code parameter to ehf_allow_ns_preemption()
When a Yielding SMC is preempted, it's possible that Non-secure world is resumed afterwards. In this case, Non-secure execution would find itself in a state where the SMC has returned. However, the dispatcher might not get an opportunity to populate the corrected return code for having been preempted, and therefore the caller of the Yielding SMC cannot reliably determine whether the SMC had successfully completed or had been preempted. To solve this, this patch introduces a new parameter to the ehf_allow_ns_preemption() API. An SPD, through this parameter, would provide the expected error code when a Yielding SMC is preempted. EHF can then populate the specified value in x0 of the Non-secure context so that the caller of the Yielding SMC correctly identifies the SMC return as a preemption. Documentation updates to follow. Change-Id: Ia9c3f8f03f9d72d81aa235eaae2ee0374b972e1e Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
Diffstat (limited to 'bl31')
-rw-r--r--bl31/ehf.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/bl31/ehf.c b/bl31/ehf.c
index 39ee6355ef..8673564f25 100644
--- a/bl31/ehf.c
+++ b/bl31/ehf.c
@@ -9,6 +9,8 @@
*/
#include <assert.h>
+#include <context.h>
+#include <context_mgmt.h>
#include <cpu_data.h>
#include <debug.h>
#include <ehf.h>
@@ -308,15 +310,17 @@ static void *ehf_entering_normal_world(const void *arg)
/*
* Program Priority Mask to the original Non-secure priority such that
* Non-secure interrupts may preempt Secure execution, viz. during Yielding SMC
- * calls.
+ * calls. The 'preempt_ret_code' parameter indicates the Yielding SMC's return
+ * value in case the call was preempted.
*
* This API is expected to be invoked before delegating a yielding SMC to Secure
* EL1. I.e. within the window of secure execution after Non-secure context is
* saved (after entry into EL3) and Secure context is restored (before entering
* Secure EL1).
*/
-void ehf_allow_ns_preemption(void)
+void ehf_allow_ns_preemption(uint64_t preempt_ret_code)
{
+ cpu_context_t *ns_ctx;
unsigned int old_pmr __unused;
pe_exc_data_t *pe_data = this_cpu_data();
@@ -333,6 +337,15 @@ void ehf_allow_ns_preemption(void)
panic();
}
+ /*
+ * Program preempted return code to x0 right away so that, if the
+ * Yielding SMC was indeed preempted before a dispatcher gets a chance
+ * to populate it, the caller would find the correct return value.
+ */
+ ns_ctx = cm_get_context(NON_SECURE);
+ assert(ns_ctx);
+ write_ctx_reg(get_gpregs_ctx(ns_ctx), CTX_GPREG_X0, preempt_ret_code);
+
old_pmr = plat_ic_set_priority_mask(pe_data->ns_pri_mask);
EHF_LOG("Priority Mask: 0x%x => 0x%x\n", old_pmr, pe_data->ns_pri_mask);