Merge pull request #1284 from jeenu-arm/tspd-ehf

TSPD and EHF
diff --git a/bl31/ehf.c b/bl31/ehf.c
index 39ee635..8673564 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 @@
 /*
  * 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 @@
 		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);
diff --git a/include/bl31/ehf.h b/include/bl31/ehf.h
index be8c957..f963f8d 100644
--- a/include/bl31/ehf.h
+++ b/include/bl31/ehf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -82,7 +82,7 @@
 void ehf_activate_priority(unsigned int priority);
 void ehf_deactivate_priority(unsigned int priority);
 void ehf_register_priority_handler(unsigned int pri, ehf_handler_t handler);
-void ehf_allow_ns_preemption(void);
+void ehf_allow_ns_preemption(uint64_t preempt_ret_code);
 unsigned int ehf_is_ns_preemption_allowed(void);
 
 #endif /* __ASSEMBLY__ */
diff --git a/services/spd/tspd/tspd_main.c b/services/spd/tspd/tspd_main.c
index c564f8b..3d06e0b 100644
--- a/services/spd/tspd/tspd_main.c
+++ b/services/spd/tspd/tspd_main.c
@@ -549,9 +549,10 @@
 				 * preempt Secure execution. However, for
 				 * yielding SMCs, we want preemption to happen;
 				 * so explicitly allow NS preemption in this
-				 * case.
+				 * case, and supply the preemption return code
+				 * for TSP.
 				 */
-				ehf_allow_ns_preemption();
+				ehf_allow_ns_preemption(TSP_PREEMPTED);
 #endif
 			}
 
@@ -662,9 +663,10 @@
 #if EL3_EXCEPTION_HANDLING
 		/*
 		 * Allow the resumed yielding SMC processing to be preempted by
-		 * Non-secure interrupts.
+		 * Non-secure interrupts. Also, supply the preemption return
+		 * code for TSP.
 		 */
-		ehf_allow_ns_preemption();
+		ehf_allow_ns_preemption(TSP_PREEMPTED);
 #endif
 
 		/* We just need to return to the preempted point in