]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
fix(rmmd): return X4 output value
authorAlexeiFedorov <Alexei.Fedorov@arm.com>
Fri, 23 Sep 2022 15:57:28 +0000 (16:57 +0100)
committerSoby Mathew <soby.mathew@arm.com>
Wed, 28 Sep 2022 13:11:03 +0000 (15:11 +0200)
Return values contained in 'smc_result' structure
are shifted down by one register:
X1 written by RMM is returned to NS in X0 and
X5 is returned in X4.

Signed-off-by: AlexeiFedorov <Alexei.Fedorov@arm.com>
Change-Id: I92907ac3ff3bac8554643ae7c198a4a758c38cb3

docs/components/rmm-el3-comms-spec.rst
services/std_svc/rmmd/rmmd_main.c

index b767958334dc9ab9c86339256f6ab87752d87c38..8070ff4464a40c7727cddc83665baa1215ea4c19 100644 (file)
@@ -494,8 +494,11 @@ EL3 must maintain a separate register context for the following:
    #. General purpose registers (x0-x30) and ``sp_el0``, ``sp_el2`` stack pointers
    #. EL2 system register context for all enabled features by EL3. These include system registers with the ``_EL2`` prefix. The EL2 physical and virtual timer registers must not be included in this.
 
-It is the responsibility of EL3 that the above registers will not be leaked to
-the NS Host and to maintain the confidentiality of the Realm World.
+As part of SMC forwarding between the NS world and Realm world, EL3 allows x0-x7 to be passed
+as arguments to Realm and x0-x4 to be used for return arguments back to Non Secure.
+As per SMCCCv1.2, x4 must be preserved if not being used as return argument by the SMC function
+and it is the responsibility of RMM to preserve this or use this as a return argument.
+EL3 will always copy x0-x4 from Realm context to NS Context.
 
 EL3 will not save some registers as mentioned in the below list. It is the
 responsibility of RMM to ensure that these are appropriately saved if the
@@ -506,6 +509,9 @@ Realm World makes use of them:
    #. SME registers
    #. EL1/0 registers
 
+It is the responsibility of EL3 that any other registers other than the ones mentioned above
+will not be leaked to the NS Host and to maintain the confidentiality of the Realm World.
+
 SMCCC v1.3 allows NS world to specify whether SVE context is in use. In this
 case, RMM could choose to not save the incoming SVE context but must ensure
 to clear SVE registers if they have been used in Realm World. The same applies
index 7cb76deab7788b8acbdf81215538900eb8e05b0b..6bd9fdf302aab5ce07aa2b0d33a93cef5fb58648 100644 (file)
@@ -242,10 +242,12 @@ int rmmd_setup(void)
  * Forward SMC to the other security state
  ******************************************************************************/
 static uint64_t        rmmd_smc_forward(uint32_t src_sec_state,
-                                       uint32_t dst_sec_state, uint64_t x0,
-                                       uint64_t x1, uint64_t x2, uint64_t x3,
-                                       uint64_t x4, void *handle)
+                                uint32_t dst_sec_state, uint64_t x0,
+                                uint64_t x1, uint64_t x2, uint64_t x3,
+                                uint64_t x4, void *handle)
 {
+       cpu_context_t *ctx = cm_get_context(dst_sec_state);
+
        /* Save incoming security state */
        cm_el1_sysregs_context_save(src_sec_state);
        cm_el2_sysregs_context_save(src_sec_state);
@@ -256,19 +258,21 @@ static uint64_t   rmmd_smc_forward(uint32_t src_sec_state,
        cm_set_next_eret_context(dst_sec_state);
 
        /*
-        * As per SMCCCv1.1, we need to preserve x4 to x7 unless
+        * As per SMCCCv1.2, we need to preserve x4 to x7 unless
         * being used as return args. Hence we differentiate the
         * onward and backward path. Support upto 8 args in the
         * onward path and 4 args in return path.
+        * Register x4 will be preserved by RMM in case it is not
+        * used in return path.
         */
        if (src_sec_state == NON_SECURE) {
-               SMC_RET8(cm_get_context(dst_sec_state), x0, x1, x2, x3, x4,
-                               SMC_GET_GP(handle, CTX_GPREG_X5),
-                               SMC_GET_GP(handle, CTX_GPREG_X6),
-                               SMC_GET_GP(handle, CTX_GPREG_X7));
-       } else {
-               SMC_RET4(cm_get_context(dst_sec_state), x0, x1, x2, x3);
+               SMC_RET8(ctx, x0, x1, x2, x3, x4,
+                        SMC_GET_GP(handle, CTX_GPREG_X5),
+                        SMC_GET_GP(handle, CTX_GPREG_X6),
+                        SMC_GET_GP(handle, CTX_GPREG_X7));
        }
+
+       SMC_RET5(ctx, x0, x1, x2, x3, x4);
 }
 
 /*******************************************************************************
@@ -276,8 +280,8 @@ static uint64_t     rmmd_smc_forward(uint32_t src_sec_state,
  * either forwarded to the other security state or handled by the RMM dispatcher
  ******************************************************************************/
 uint64_t rmmd_rmi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
-                               uint64_t x3, uint64_t x4, void *cookie,
-                               void *handle, uint64_t flags)
+                         uint64_t x3, uint64_t x4, void *cookie,
+                         void *handle, uint64_t flags)
 {
        uint32_t src_sec_state;
 
@@ -311,10 +315,12 @@ uint64_t rmmd_rmi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
        }
 
        switch (smc_fid) {
-       case RMM_RMI_REQ_COMPLETE:
-               return rmmd_smc_forward(REALM, NON_SECURE, x1,
-                                       x2, x3, x4, 0, handle);
+       case RMM_RMI_REQ_COMPLETE: {
+               uint64_t x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 
+               return rmmd_smc_forward(REALM, NON_SECURE, x1,
+                                       x2, x3, x4, x5, handle);
+       }
        default:
                WARN("RMMD: Unsupported RMM call 0x%08x\n", smc_fid);
                SMC_RET1(handle, SMC_UNK);