Stack_seal_mitigation: Seal stack for interrupt deprivileging

Seal the handler mode stack (MSP) in case of interrupt deprivileging
for Function mode. The interrupt deprivileging is acheived by the ISR
calling an SVC and a seal is applied on MSP before the interrupt is
deprivileged. Other exceptions such as faults runs to panic so there
is no need of sealing caller contexts for these exceptions.

This patch also removes the separate inline assembly implementation for
Mainline as the benefit of a single code to maintain and patch far
outweigh any benefits gained by a separate implementation.

Change-Id: I8fdff140f4157882853e3abd24cc23b7e68ee0a3
Signed-off-by: Ken Liu <ken.liu@arm.com>
Signed-off-by: Mate Toth-Pal <mate.toth-pal@arm.com>
Signed-off-by: Soby Mathew <soby.mathew@arm.com>
diff --git a/secure_fw/spm/arch/tfm_arch_v8m_base.c b/secure_fw/spm/arch/tfm_arch_v8m_base.c
index 0c5d834..2664daa 100644
--- a/secure_fw/spm/arch/tfm_arch_v8m_base.c
+++ b/secure_fw/spm/arch/tfm_arch_v8m_base.c
@@ -198,17 +198,38 @@
 __attribute__((naked)) void SVC_Handler(void)
 {
     __ASM volatile(
+#if !defined(__ICCARM__)
+    ".syntax unified                        \n"
+#endif
+    "MRS     r0, PSP                        \n"
     "MRS     r2, MSP                        \n"
     "MOVS    r1, #4                         \n"
     "MOV     r3, lr                         \n"
-    "MOV     r0, r2                         \n"
     "TST     r1, r3                         \n"
-    "BEQ     handler                        \n"
-    /* If SVC was made from thread mode, overwrite r0 with PSP */
-    "MRS     r0, PSP                        \n"
-    "handler:                               \n"
+    "BNE     from_thread                    \n"
+    /*
+     * This branch is taken when the code is being invoked from handler mode.
+     * This happens when a de-privileged interrupt handler is to be run. Seal
+     * the stack before de-privileging.
+     */
+    "LDR     r0, =0xFEF5EDA5                \n"
+    "MOVS    r3, r0                         \n"
+    "PUSH    {r0, r3}                       \n"
+    /* Overwrite r0 with MSP */
+    "MOV     r0, r2                         \n"
+    "from_thread:                           \n"
     "MOV     r1, lr                         \n"
     "BL      tfm_core_svc_handler           \n"
+    "MOVS    r1, #4                         \n"
+    "TST     r1, r0                         \n"
+    "BNE     to_thread                      \n"
+    /*
+     * This branch is taken when the code is going to return to handler mode.
+     * This happens after a de-privileged interrupt handler had been run. Pop
+     * the sealing from the stack.
+     */
+    "POP     {r1, r2}                       \n"
+    "to_thread:                             \n"
     "BX      r0                             \n"
     );
 }
diff --git a/secure_fw/spm/arch/tfm_arch_v8m_main.c b/secure_fw/spm/arch/tfm_arch_v8m_main.c
index be268ec..cb99b20 100644
--- a/secure_fw/spm/arch/tfm_arch_v8m_main.c
+++ b/secure_fw/spm/arch/tfm_arch_v8m_main.c
@@ -193,14 +193,38 @@
 __attribute__((naked)) void SVC_Handler(void)
 {
     __ASM volatile(
+#if !defined(__ICCARM__)
+    ".syntax unified                        \n"
+#endif
+    "MRS     r0, PSP                        \n"
     "MRS     r2, MSP                        \n"
-    /* Check store SP in thread mode to r0 */
-    "TST     lr, #4                         \n"
-    "ITE     EQ                             \n"
-    "MOVEQ   r0, r2                         \n"
-    "MRSNE   r0, PSP                        \n"
+    "MOVS    r1, #4                         \n"
+    "MOV     r3, lr                         \n"
+    "TST     r1, r3                         \n"
+    "BNE     from_thread                    \n"
+    /*
+     * This branch is taken when the code is being invoked from handler mode.
+     * This happens when a de-privileged interrupt handler is to be run. Seal
+     * the stack before de-privileging.
+     */
+    "LDR     r0, =0xFEF5EDA5                \n"
+    "MOVS    r3, r0                         \n"
+    "PUSH    {r0, r3}                       \n"
+    /* Overwrite r0 with MSP */
+    "MOV     r0, r2                         \n"
+    "from_thread:                           \n"
     "MOV     r1, lr                         \n"
     "BL      tfm_core_svc_handler           \n"
+    "MOVS    r1, #4                         \n"
+    "TST     r1, r0                         \n"
+    "BNE     to_thread                      \n"
+    /*
+     * This branch is taken when the code is going to return to handler mode.
+     * This happens after a de-privileged interrupt handler had been run. Pop
+     * the sealing from the stack.
+     */
+    "POP     {r1, r2}                       \n"
+    "to_thread:                             \n"
     "BX      r0                             \n"
     );
 }
diff --git a/secure_fw/spm/model_func/spm_func.c b/secure_fw/spm/model_func/spm_func.c
index 96d90de..6b8575f 100644
--- a/secure_fw/spm/model_func/spm_func.c
+++ b/secure_fw/spm/model_func/spm_func.c
@@ -933,8 +933,12 @@
 uint32_t tfm_spm_depriv_return_handler(uint32_t *irq_svc_args, uint32_t lr)
 {
     enum tfm_status_e res;
-    struct tfm_state_context_t *irq_svc_ctx =
-                                    (struct tfm_state_context_t *)irq_svc_args;
+    struct tfm_state_context_t *irq_svc_ctx;
+
+    /* Take into account the sealed stack*/
+    irq_svc_args += 2;
+
+    irq_svc_ctx = (struct tfm_state_context_t *)irq_svc_args;
 
     if (!(lr & EXC_RETURN_STACK_PROCESS)) {
         /* Partition request SVC called with MSP active.