summaryrefslogtreecommitdiff
path: root/bl31
diff options
context:
space:
mode:
authorMadhukar Pappireddy <madhukar.pappireddy@arm.com>2019-05-08 15:41:41 -0500
committerSandrine Bailleux <sandrine.bailleux@arm.com>2019-05-21 08:19:37 +0000
commitcc485e27acdcc237718d0c10efd0526b2cf2513a (patch)
tree24f725114735b0959cdea0e200a96cadae7faa0e /bl31
parentaf9ae7cfa169e8c2e812f07014144fe247378ead (diff)
Rework smc_unknown return code path in smc_handler
The intention of this patch is to leverage the existing el3_exit() return routine for smc_unknown return path rather than a custom set of instructions. In order to leverage el3_exit(), the necessary counteraction (i.e., saving the system registers apart from GP registers) must be performed. Hence a series of instructions which save system registers( like SPSR_EL3, SCR_EL3 etc) to stack are moved to the top of group of instructions which essentially decode the OEN from the smc function identifier and obtain the specific service handler in rt_svc_descs_array. This ensures that the control flow for both known and unknown smc calls will be similar. Change-Id: I67f94cfcba176bf8aee1a446fb58a4e383905a87 Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
Diffstat (limited to 'bl31')
-rw-r--r--bl31/aarch64/runtime_exceptions.S57
1 files changed, 28 insertions, 29 deletions
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 1734d7ec..6ffd9955 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -352,28 +352,6 @@ smc_handler64:
mov x5, xzr
mov x6, sp
- /* Get the unique owning entity number */
- ubfx x16, x0, #FUNCID_OEN_SHIFT, #FUNCID_OEN_WIDTH
- ubfx x15, x0, #FUNCID_TYPE_SHIFT, #FUNCID_TYPE_WIDTH
- orr x16, x16, x15, lsl #FUNCID_OEN_WIDTH
-
- /* Load descriptor index from array of indices */
- adr x14, rt_svc_descs_indices
- ldrb w15, [x14, x16]
-
- /* Any index greater than 127 is invalid. Check bit 7. */
- tbnz w15, 7, smc_unknown
-
- /*
- * Get the descriptor using the index
- * x11 = (base + off), w15 = index
- *
- * handler = (base + off) + (index << log2(size))
- */
- adr x11, (__RT_SVC_DESCS_START__ + RT_SVC_DESC_HANDLE)
- lsl w10, w15, #RT_SVC_SIZE_LOG2
- ldr x15, [x11, w10, uxtw]
-
/*
* Restore the saved C runtime stack value which will become the new
* SP_EL0 i.e. EL3 runtime stack. It was saved in the 'cpu_context'
@@ -400,6 +378,28 @@ smc_handler64:
mov sp, x12
+ /* Get the unique owning entity number */
+ ubfx x16, x0, #FUNCID_OEN_SHIFT, #FUNCID_OEN_WIDTH
+ ubfx x15, x0, #FUNCID_TYPE_SHIFT, #FUNCID_TYPE_WIDTH
+ orr x16, x16, x15, lsl #FUNCID_OEN_WIDTH
+
+ /* Load descriptor index from array of indices */
+ adr x14, rt_svc_descs_indices
+ ldrb w15, [x14, x16]
+
+ /* Any index greater than 127 is invalid. Check bit 7. */
+ tbnz w15, 7, smc_unknown
+
+ /*
+ * Get the descriptor using the index
+ * x11 = (base + off), w15 = index
+ *
+ * handler = (base + off) + (index << log2(size))
+ */
+ adr x11, (__RT_SVC_DESCS_START__ + RT_SVC_DESC_HANDLE)
+ lsl w10, w15, #RT_SVC_SIZE_LOG2
+ ldr x15, [x11, w10, uxtw]
+
/*
* Call the Secure Monitor Call handler and then drop directly into
* el3_exit() which will program any remaining architectural state
@@ -414,15 +414,14 @@ smc_handler64:
smc_unknown:
/*
- * Unknown SMC call. Populate return value with SMC_UNK, restore
- * GP registers, and return to caller.
+ * Unknown SMC call. Populate return value with SMC_UNK and call
+ * el3_exit() which will restore the remaining architectural state
+ * i.e., SYS, GP and PAuth registers(if any) prior to issuing the ERET
+ * to the desired lower EL.
*/
mov x0, #SMC_UNK
- str x0, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
-#if CTX_INCLUDE_PAUTH_REGS
- bl pauth_context_restore
-#endif
- b restore_gp_registers_eret
+ str x0, [x6, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
+ b el3_exit
smc_prohibited:
ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]