Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb5b0e61 authored by Joonwoo Park's avatar Joonwoo Park Committed by Lingutla Chandrasekhar
Browse files

sched: prevent out of bound access in sched_group_energy()



group_idle_state() can return INT_MAX + 1 which is undefined behaviour
when there is no CPUs in sched_group.  Prevent such by error correctly.

Change-Id: If9796c829c091e461231569dc38c5e5456f58037
Signed-off-by: default avatarJoonwoo Park <joonwoop@codeaurora.org>
Signed-off-by: default avatarSatya Durga Srinivasu Prabhala <satyap@codeaurora.org>
[clingutla@codeaurora.org: Fixed trivial merge conflicts and squashed
  msm-4.14 change]
Signed-off-by: default avatarLingutla Chandrasekhar <clingutla@codeaurora.org>
parent 3c599c7a
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -5710,6 +5710,9 @@ static int group_idle_state(struct energy_env *eenv, int cpu_idx)
	for_each_cpu(i, sched_group_cpus(sg))
		state = min(state, idle_get_state_idx(cpu_rq(i)));

	if (unlikely(state == INT_MAX))
		return -EINVAL;

	/* Take non-cpuidle idling into account (active idle/arch_cpu_idle()) */
	state++;

@@ -5776,7 +5779,7 @@ static int group_idle_state(struct energy_env *eenv, int cpu_idx)
 * The required scaling will be performed just one time, by the calling
 * functions, once we accumulated the contributons for all the SGs.
 */
static void calc_sg_energy(struct energy_env *eenv)
static int calc_sg_energy(struct energy_env *eenv)
{
	struct sched_group *sg = eenv->sg;
	int busy_energy, idle_energy;
@@ -5805,6 +5808,8 @@ static void calc_sg_energy(struct energy_env *eenv)

		/* Compute IDLE energy */
		idle_idx = group_idle_state(eenv, cpu_idx);
		if (unlikely(idle_idx < 0))
			return idle_idx;
		idle_power = sg->sge->idle_states[idle_idx].power;

		idle_energy   = SCHED_CAPACITY_SCALE - sg_util;
@@ -5813,6 +5818,7 @@ static void calc_sg_energy(struct energy_env *eenv)
		total_energy = busy_energy + idle_energy;
		eenv->cpu[cpu_idx].energy += total_energy;
	}
	return 0;
}

/*
@@ -5874,7 +5880,8 @@ static int compute_energy(struct energy_env *eenv)
				 * CPUs in the current visited SG.
				 */
				eenv->sg = sg;
				calc_sg_energy(eenv);
				if (calc_sg_energy(eenv))
					return -EINVAL;

				/* remove CPUs we have just visited */
				if (!sd->child) {