Commit aa3ee06a authored by Jacob Pan's avatar Jacob Pan Committed by Greg Kroah-Hartman

powercap/intel_rapl: fix and tidy up error handling

commit cb43f81b upstream.

Commit e1399ba2 ("powercap / RAPL: handle missing MSRs") added
contraint_to_pl() function to return index into an array. But it
can potentially return -EINVAL if powercap layer sends an out of
range constraint ID. This patch adds sanity check.

Unnecessary RAPL domain pointer check is removed since it must be
initialized before calling rapl_unit_xlate().

Fixes: e1399ba2 ("powercap / RAPL: handle missing MSRs")
Reported-by: default avatarOdzioba, Lukasz <lukasz.odzioba@intel.com>
Reported-by: default avatarKoss, Marcin <marcin.koss@intel.com>
Signed-off-by: default avatarJacob Pan <jacob.jun.pan@linux.intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f53cfb08
...@@ -442,6 +442,7 @@ static int contraint_to_pl(struct rapl_domain *rd, int cid) ...@@ -442,6 +442,7 @@ static int contraint_to_pl(struct rapl_domain *rd, int cid)
return i; return i;
} }
} }
pr_err("Cannot find matching power limit for constraint %d\n", cid);
return -EINVAL; return -EINVAL;
} }
...@@ -457,6 +458,10 @@ static int set_power_limit(struct powercap_zone *power_zone, int cid, ...@@ -457,6 +458,10 @@ static int set_power_limit(struct powercap_zone *power_zone, int cid,
get_online_cpus(); get_online_cpus();
rd = power_zone_to_rapl_domain(power_zone); rd = power_zone_to_rapl_domain(power_zone);
id = contraint_to_pl(rd, cid); id = contraint_to_pl(rd, cid);
if (id < 0) {
ret = id;
goto set_exit;
}
rp = rd->rp; rp = rd->rp;
...@@ -496,6 +501,11 @@ static int get_current_power_limit(struct powercap_zone *power_zone, int cid, ...@@ -496,6 +501,11 @@ static int get_current_power_limit(struct powercap_zone *power_zone, int cid,
get_online_cpus(); get_online_cpus();
rd = power_zone_to_rapl_domain(power_zone); rd = power_zone_to_rapl_domain(power_zone);
id = contraint_to_pl(rd, cid); id = contraint_to_pl(rd, cid);
if (id < 0) {
ret = id;
goto get_exit;
}
switch (rd->rpl[id].prim_id) { switch (rd->rpl[id].prim_id) {
case PL1_ENABLE: case PL1_ENABLE:
prim = POWER_LIMIT1; prim = POWER_LIMIT1;
...@@ -512,6 +522,7 @@ static int get_current_power_limit(struct powercap_zone *power_zone, int cid, ...@@ -512,6 +522,7 @@ static int get_current_power_limit(struct powercap_zone *power_zone, int cid,
else else
*data = val; *data = val;
get_exit:
put_online_cpus(); put_online_cpus();
return ret; return ret;
...@@ -527,6 +538,10 @@ static int set_time_window(struct powercap_zone *power_zone, int cid, ...@@ -527,6 +538,10 @@ static int set_time_window(struct powercap_zone *power_zone, int cid,
get_online_cpus(); get_online_cpus();
rd = power_zone_to_rapl_domain(power_zone); rd = power_zone_to_rapl_domain(power_zone);
id = contraint_to_pl(rd, cid); id = contraint_to_pl(rd, cid);
if (id < 0) {
ret = id;
goto set_time_exit;
}
switch (rd->rpl[id].prim_id) { switch (rd->rpl[id].prim_id) {
case PL1_ENABLE: case PL1_ENABLE:
...@@ -538,6 +553,8 @@ static int set_time_window(struct powercap_zone *power_zone, int cid, ...@@ -538,6 +553,8 @@ static int set_time_window(struct powercap_zone *power_zone, int cid,
default: default:
ret = -EINVAL; ret = -EINVAL;
} }
set_time_exit:
put_online_cpus(); put_online_cpus();
return ret; return ret;
} }
...@@ -552,6 +569,10 @@ static int get_time_window(struct powercap_zone *power_zone, int cid, u64 *data) ...@@ -552,6 +569,10 @@ static int get_time_window(struct powercap_zone *power_zone, int cid, u64 *data)
get_online_cpus(); get_online_cpus();
rd = power_zone_to_rapl_domain(power_zone); rd = power_zone_to_rapl_domain(power_zone);
id = contraint_to_pl(rd, cid); id = contraint_to_pl(rd, cid);
if (id < 0) {
ret = id;
goto get_time_exit;
}
switch (rd->rpl[id].prim_id) { switch (rd->rpl[id].prim_id) {
case PL1_ENABLE: case PL1_ENABLE:
...@@ -566,6 +587,8 @@ static int get_time_window(struct powercap_zone *power_zone, int cid, u64 *data) ...@@ -566,6 +587,8 @@ static int get_time_window(struct powercap_zone *power_zone, int cid, u64 *data)
} }
if (!ret) if (!ret)
*data = val; *data = val;
get_time_exit:
put_online_cpus(); put_online_cpus();
return ret; return ret;
...@@ -707,7 +730,7 @@ static u64 rapl_unit_xlate(struct rapl_domain *rd, enum unit_type type, ...@@ -707,7 +730,7 @@ static u64 rapl_unit_xlate(struct rapl_domain *rd, enum unit_type type,
case ENERGY_UNIT: case ENERGY_UNIT:
scale = ENERGY_UNIT_SCALE; scale = ENERGY_UNIT_SCALE;
/* per domain unit takes precedence */ /* per domain unit takes precedence */
if (rd && rd->domain_energy_unit) if (rd->domain_energy_unit)
units = rd->domain_energy_unit; units = rd->domain_energy_unit;
else else
units = rp->energy_unit; units = rp->energy_unit;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment