PSCI: Fix the return code for invalid entrypoint
authorSoby Mathew <soby.mathew@arm.com>
Wed, 15 Jul 2015 11:13:26 +0000 (12:13 +0100)
committerAchin Gupta <achin.gupta@arm.com>
Thu, 13 Aug 2015 22:48:07 +0000 (23:48 +0100)
As per PSCI1.0 specification, the error code to be returned when an invalid
non secure entrypoint address is specified by the PSCI client for CPU_SUSPEND,
CPU_ON or SYSTEM_SUSPEND must be PSCI_E_INVALID_ADDRESS. The current PSCI
implementation returned PSCI_E_INVAL_PARAMS. This patch rectifies this error
and also implements a common helper function to validate the entrypoint
information to be used across these PSCI API implementations.

Change-Id: I52d697d236c8bf0cd3297da4008c8e8c2399b170

include/bl31/services/psci.h
services/std_svc/psci/psci_common.c
services/std_svc/psci/psci_main.c
services/std_svc/psci/psci_private.h

index c9b3f8d2c77457a68e6758b6b82b87fa6b6ee44c..f6fd4872c11410d5ac6f23aa86be042bbf309495 100644 (file)
 #define PSCI_E_INTERN_FAIL     -6
 #define PSCI_E_NOT_PRESENT     -7
 #define PSCI_E_DISABLED                -8
+#define PSCI_E_INVALID_ADDRESS -9
 
 #define PSCI_INVALID_MPIDR     ~(0ULL)
 
index 7f1a5fd0d8db1dc475fdfba16a687c556486be65..f810ddfac56788a585e5fd6052c75460b2b676ac 100644 (file)
@@ -589,7 +589,7 @@ int psci_validate_mpidr(unsigned long mpidr)
  * This function determines the full entrypoint information for the requested
  * PSCI entrypoint on power on/resume and returns it.
  ******************************************************************************/
-int psci_get_ns_ep_info(entry_point_info_t *ep,
+static int psci_get_ns_ep_info(entry_point_info_t *ep,
                       uint64_t entrypoint, uint64_t context_id)
 {
        uint32_t ep_attr, mode, sctlr, daif, ee;
@@ -621,7 +621,7 @@ int psci_get_ns_ep_info(entry_point_info_t *ep,
                 * aarch64 EL
                 */
                if (entrypoint & 0x1)
-                       return PSCI_E_INVALID_PARAMS;
+                       return PSCI_E_INVALID_ADDRESS;
 
                mode = ns_scr_el3 & SCR_HCE_BIT ? MODE_EL2 : MODE_EL1;
 
@@ -642,6 +642,32 @@ int psci_get_ns_ep_info(entry_point_info_t *ep,
        return PSCI_E_SUCCESS;
 }
 
+/*******************************************************************************
+ * This function validates the entrypoint with the platform layer if the
+ * appropriate pm_ops hook is exported by the platform and returns the
+ * 'entry_point_info'.
+ ******************************************************************************/
+int psci_validate_entry_point(entry_point_info_t *ep,
+                      uint64_t entrypoint, uint64_t context_id)
+{
+       int rc;
+
+       /* Validate the entrypoint using platform psci_ops */
+       if (psci_plat_pm_ops->validate_ns_entrypoint) {
+               rc = psci_plat_pm_ops->validate_ns_entrypoint(entrypoint);
+               if (rc != PSCI_E_SUCCESS)
+                       return PSCI_E_INVALID_ADDRESS;
+       }
+
+       /*
+        * Verify and derive the re-entry information for
+        * the non-secure world from the non-secure state from
+        * where this call originated.
+        */
+       rc = psci_get_ns_ep_info(ep, entrypoint, context_id);
+       return rc;
+}
+
 /*******************************************************************************
  * Generic handler which is called when a cpu is physically powered on. It
  * traverses the node information and finds the highest power level powered
index f02429102260b49833b6eaedb7b23beb5c0b44b4..6d3af20480fda95dcd68416afdeee02d530e9a83 100644 (file)
@@ -55,21 +55,8 @@ int psci_cpu_on(unsigned long target_cpu,
        if (rc != PSCI_E_SUCCESS)
                return PSCI_E_INVALID_PARAMS;
 
-       /* Validate the entrypoint using platform pm_ops */
-       if (psci_plat_pm_ops->validate_ns_entrypoint) {
-               rc = psci_plat_pm_ops->validate_ns_entrypoint(entrypoint);
-               if (rc != PSCI_E_SUCCESS) {
-                       assert(rc == PSCI_E_INVALID_PARAMS);
-                       return PSCI_E_INVALID_PARAMS;
-               }
-       }
-
-       /*
-        * Verify and derive the re-entry information for
-        * the non-secure world from the non-secure state from
-        * where this call originated.
-        */
-       rc = psci_get_ns_ep_info(&ep, entrypoint, context_id);
+       /* Validate the entry point and get the entry_point_info */
+       rc = psci_validate_entry_point(&ep, entrypoint, context_id);
        if (rc != PSCI_E_SUCCESS)
                return rc;
 
@@ -141,20 +128,7 @@ int psci_cpu_suspend(unsigned int power_state,
         * point and program entry information.
         */
        if (is_power_down_state) {
-               if (psci_plat_pm_ops->validate_ns_entrypoint) {
-                       rc = psci_plat_pm_ops->validate_ns_entrypoint(entrypoint);
-                       if (rc != PSCI_E_SUCCESS) {
-                               assert(rc == PSCI_E_INVALID_PARAMS);
-                               return rc;
-                       }
-               }
-
-               /*
-                * Verify and derive the re-entry information for
-                * the non-secure world from the non-secure state from
-                * where this call originated.
-                */
-               rc = psci_get_ns_ep_info(&ep, entrypoint, context_id);
+               rc = psci_validate_entry_point(&ep, entrypoint, context_id);
                if (rc != PSCI_E_SUCCESS)
                        return rc;
        }
@@ -180,25 +154,12 @@ int psci_system_suspend(unsigned long entrypoint,
        psci_power_state_t state_info;
        entry_point_info_t ep;
 
-       /* Validate the entrypoint using platform pm_ops */
-       if (psci_plat_pm_ops->validate_ns_entrypoint) {
-               rc = psci_plat_pm_ops->validate_ns_entrypoint(entrypoint);
-               if (rc != PSCI_E_SUCCESS) {
-                       assert(rc == PSCI_E_INVALID_PARAMS);
-                       return rc;
-               }
-       }
-
        /* Check if the current CPU is the last ON CPU in the system */
        if (!psci_is_last_on_cpu())
                return PSCI_E_DENIED;
 
-       /*
-        * Verify and derive the re-entry information for
-        * the non-secure world from the non-secure state from
-        * where this call originated.
-        */
-       rc = psci_get_ns_ep_info(&ep, entrypoint, context_id);
+       /* Validate the entry point and get the entry_point_info */
+       rc = psci_validate_entry_point(&ep, entrypoint, context_id);
        if (rc != PSCI_E_SUCCESS)
                return rc;
 
index e2e32c796230e0523e24687dd036c67029de5e67..5345ee30fd4914ec095263c44c1a30a4e4ee76e8 100644 (file)
@@ -189,7 +189,7 @@ void psci_query_sys_suspend_pwrstate(psci_power_state_t *state_info);
 int psci_validate_mpidr(unsigned long mpidr);
 void psci_init_req_local_pwr_states(void);
 void psci_power_up_finish(void);
-int psci_get_ns_ep_info(entry_point_info_t *ep,
+int psci_validate_entry_point(entry_point_info_t *ep,
                       uint64_t entrypoint, uint64_t context_id);
 void psci_get_parent_pwr_domain_nodes(unsigned int cpu_idx,
                                      int end_lvl,