summaryrefslogtreecommitdiff
path: root/services/std_svc/psci/psci_setup.c
diff options
context:
space:
mode:
authorSoby Mathew <soby.mathew@arm.com>2014-10-02 17:24:19 +0100
committerSoby Mathew <soby.mathew@arm.com>2014-12-12 13:53:07 +0000
commit264999fc601e5b72e31aeb66101b57e409e2f68b (patch)
treeb3b87aaaf0f3a9f914a563f8c402c40e1e0777f8 /services/std_svc/psci/psci_setup.c
parent29e32cba4ad243071c643c839dfd4f46a0b19655 (diff)
Fix CPU_SUSPEND when invoked with affinity level higher than get_max_afflvl()
This patch fixes the assertion failure when CPU_SUSPEND is invoked with an affinity level higher than supported by the platform by adding suitable checks for affinity level within `psci_cpu_suspend`. Also added suitable bound checks within `psci_aff_map_get_idx` to prevent indexing beyond array limits. Fixes ARM-software/tf-issues#260 Change-Id: I04b75c49729e6c6d1983add590f60146c8fc3630
Diffstat (limited to 'services/std_svc/psci/psci_setup.c')
-rw-r--r--services/std_svc/psci/psci_setup.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/services/std_svc/psci/psci_setup.c b/services/std_svc/psci/psci_setup.c
index a5ae4ef5..8e9d15dc 100644
--- a/services/std_svc/psci/psci_setup.c
+++ b/services/std_svc/psci/psci_setup.c
@@ -77,12 +77,18 @@ static int psci_aff_map_get_idx(unsigned long key,
return PSCI_E_INVALID_PARAMS;
/*
+ * Make sure we are within array limits.
+ */
+ assert(min_idx >= 0 && max_idx < PSCI_NUM_AFFS);
+
+ /*
* Bisect the array around 'mid' and then recurse into the array chunk
* where the key is likely to be found. The mpidrs in each node in the
* 'psci_aff_map' for a given affinity level are stored in an ascending
* order which makes the binary search possible.
*/
mid = min_idx + ((max_idx - min_idx) >> 1); /* Divide by 2 */
+
if (psci_aff_map[mid].mpidr > key)
return psci_aff_map_get_idx(key, min_idx, mid - 1);
else if (psci_aff_map[mid].mpidr < key)
@@ -95,6 +101,9 @@ aff_map_node_t *psci_get_aff_map_node(unsigned long mpidr, int aff_lvl)
{
int rc;
+ if (aff_lvl > get_max_afflvl())
+ return NULL;
+
/* Right shift the mpidr to the required affinity level */
mpidr = mpidr_mask_lower_afflvls(mpidr, aff_lvl);