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
This commit is contained in:
parent
29e32cba4a
commit
264999fc60
|
@ -201,7 +201,7 @@ unsigned long mpidr_set_aff_inst(unsigned long mpidr,
|
|||
int psci_check_afflvl_range(int start_afflvl, int end_afflvl)
|
||||
{
|
||||
/* Sanity check the parameters passed */
|
||||
if (end_afflvl > MPIDR_MAX_AFFLVL)
|
||||
if (end_afflvl > get_max_afflvl())
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
|
||||
if (start_afflvl < MPIDR_AFFLVL0)
|
||||
|
|
|
@ -86,7 +86,7 @@ int psci_cpu_suspend(unsigned int power_state,
|
|||
|
||||
/* Sanity check the requested state */
|
||||
target_afflvl = psci_get_pstate_afflvl(power_state);
|
||||
if (target_afflvl > MPIDR_MAX_AFFLVL)
|
||||
if (target_afflvl > get_max_afflvl())
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
|
||||
/* Determine the 'state type' in the 'power_state' parameter */
|
||||
|
|
|
@ -76,6 +76,11 @@ static int psci_aff_map_get_idx(unsigned long key,
|
|||
if (max_idx < min_idx)
|
||||
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
|
||||
|
@ -83,6 +88,7 @@ static int psci_aff_map_get_idx(unsigned long key,
|
|||
* 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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue