Skip to content

Commit 07d53b6

Browse files
Sumit GuptajamieNguyenNVIDIA
authored andcommitted
ACPI: CPPC: Check cpc_read() return values consistently
Callers of cpc_read() ignore its return value, which can lead to using uninitialized or stale values when the read fails. Fix this by consistently checking cpc_read() return values in cppc_get_perf_caps(), cppc_get_perf_ctrs(), and cppc_get_perf(). Link: https://lore.kernel.org/lkml/48bdf87e-39f1-402f-a7dc-1a0e1e7a819d@nvidia.com/ Suggested-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Sumit Gupta <sumitg@nvidia.com> Link: https://patch.msgid.link/20260318095005.2437960-1-sumitg@nvidia.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> (backported from commit 0cc2497) [jamien: adapted for tree without reference_perf handling in cppc_get_perf_caps(), and with additional ref_perf read in cppc_get_perf_ctrs()] Signed-off-by: Jamie Nguyen <jamien@nvidia.com>
1 parent 85564c6 commit 07d53b6

1 file changed

Lines changed: 69 additions & 25 deletions

File tree

drivers/acpi/cppc_acpi.c

Lines changed: 69 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,35 +1392,53 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
13921392
}
13931393
}
13941394

1395-
cpc_read(cpunum, highest_reg, &high);
1395+
ret = cpc_read(cpunum, highest_reg, &high);
1396+
if (ret)
1397+
goto out_err;
13961398
perf_caps->highest_perf = high;
13971399

1398-
cpc_read(cpunum, lowest_reg, &low);
1400+
ret = cpc_read(cpunum, lowest_reg, &low);
1401+
if (ret)
1402+
goto out_err;
13991403
perf_caps->lowest_perf = low;
14001404

1401-
cpc_read(cpunum, nominal_reg, &nom);
1405+
ret = cpc_read(cpunum, nominal_reg, &nom);
1406+
if (ret)
1407+
goto out_err;
14021408
perf_caps->nominal_perf = nom;
14031409

14041410
if (guaranteed_reg->type != ACPI_TYPE_BUFFER ||
14051411
IS_NULL_REG(&guaranteed_reg->cpc_entry.reg)) {
14061412
perf_caps->guaranteed_perf = 0;
14071413
} else {
1408-
cpc_read(cpunum, guaranteed_reg, &guaranteed);
1414+
ret = cpc_read(cpunum, guaranteed_reg, &guaranteed);
1415+
if (ret)
1416+
goto out_err;
14091417
perf_caps->guaranteed_perf = guaranteed;
14101418
}
14111419

1412-
cpc_read(cpunum, lowest_non_linear_reg, &min_nonlinear);
1420+
ret = cpc_read(cpunum, lowest_non_linear_reg, &min_nonlinear);
1421+
if (ret)
1422+
goto out_err;
14131423
perf_caps->lowest_nonlinear_perf = min_nonlinear;
14141424

1415-
if (!high || !low || !nom || !min_nonlinear)
1425+
if (!high || !low || !nom || !min_nonlinear) {
14161426
ret = -EFAULT;
1427+
goto out_err;
1428+
}
14171429

14181430
/* Read optional lowest and nominal frequencies if present */
1419-
if (CPC_SUPPORTED(low_freq_reg))
1420-
cpc_read(cpunum, low_freq_reg, &low_f);
1431+
if (CPC_SUPPORTED(low_freq_reg)) {
1432+
ret = cpc_read(cpunum, low_freq_reg, &low_f);
1433+
if (ret)
1434+
goto out_err;
1435+
}
14211436

1422-
if (CPC_SUPPORTED(nom_freq_reg))
1423-
cpc_read(cpunum, nom_freq_reg, &nom_f);
1437+
if (CPC_SUPPORTED(nom_freq_reg)) {
1438+
ret = cpc_read(cpunum, nom_freq_reg, &nom_f);
1439+
if (ret)
1440+
goto out_err;
1441+
}
14241442

14251443
perf_caps->lowest_freq = low_f;
14261444
perf_caps->nominal_freq = nom_f;
@@ -1526,18 +1544,29 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
15261544
}
15271545
}
15281546

1529-
cpc_read(cpunum, delivered_reg, &delivered);
1530-
cpc_read(cpunum, reference_reg, &reference);
1531-
cpc_read(cpunum, ref_perf_reg, &ref_perf);
1547+
ret = cpc_read(cpunum, delivered_reg, &delivered);
1548+
if (ret)
1549+
goto out_err;
1550+
1551+
ret = cpc_read(cpunum, reference_reg, &reference);
1552+
if (ret)
1553+
goto out_err;
1554+
1555+
ret = cpc_read(cpunum, ref_perf_reg, &ref_perf);
1556+
if (ret)
1557+
goto out_err;
15321558

15331559
/*
15341560
* Per spec, if ctr_wrap_time optional register is unsupported, then the
15351561
* performance counters are assumed to never wrap during the lifetime of
15361562
* platform
15371563
*/
15381564
ctr_wrap_time = (u64)(~((u64)0));
1539-
if (CPC_SUPPORTED(ctr_wrap_reg))
1540-
cpc_read(cpunum, ctr_wrap_reg, &ctr_wrap_time);
1565+
if (CPC_SUPPORTED(ctr_wrap_reg)) {
1566+
ret = cpc_read(cpunum, ctr_wrap_reg, &ctr_wrap_time);
1567+
if (ret)
1568+
goto out_err;
1569+
}
15411570

15421571
if (!delivered || !reference || !ref_perf) {
15431572
ret = -EFAULT;
@@ -1814,24 +1843,39 @@ int cppc_get_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
18141843
}
18151844

18161845
/* Read optional elements if present */
1817-
if (CPC_SUPPORTED(max_perf_reg))
1818-
cpc_read(cpu, max_perf_reg, &max);
1846+
if (CPC_SUPPORTED(max_perf_reg)) {
1847+
ret = cpc_read(cpu, max_perf_reg, &max);
1848+
if (ret)
1849+
goto out_err;
1850+
}
18191851
perf_ctrls->max_perf = max;
18201852

1821-
if (CPC_SUPPORTED(min_perf_reg))
1822-
cpc_read(cpu, min_perf_reg, &min);
1853+
if (CPC_SUPPORTED(min_perf_reg)) {
1854+
ret = cpc_read(cpu, min_perf_reg, &min);
1855+
if (ret)
1856+
goto out_err;
1857+
}
18231858
perf_ctrls->min_perf = min;
18241859

1825-
if (CPC_SUPPORTED(desired_perf_reg))
1826-
cpc_read(cpu, desired_perf_reg, &desired_perf);
1860+
if (CPC_SUPPORTED(desired_perf_reg)) {
1861+
ret = cpc_read(cpu, desired_perf_reg, &desired_perf);
1862+
if (ret)
1863+
goto out_err;
1864+
}
18271865
perf_ctrls->desired_perf = desired_perf;
18281866

1829-
if (CPC_SUPPORTED(energy_perf_reg))
1830-
cpc_read(cpu, energy_perf_reg, &energy_perf);
1867+
if (CPC_SUPPORTED(energy_perf_reg)) {
1868+
ret = cpc_read(cpu, energy_perf_reg, &energy_perf);
1869+
if (ret)
1870+
goto out_err;
1871+
}
18311872
perf_ctrls->energy_perf = energy_perf;
18321873

1833-
if (CPC_SUPPORTED(auto_sel_reg))
1834-
cpc_read(cpu, auto_sel_reg, &auto_sel);
1874+
if (CPC_SUPPORTED(auto_sel_reg)) {
1875+
ret = cpc_read(cpu, auto_sel_reg, &auto_sel);
1876+
if (ret)
1877+
goto out_err;
1878+
}
18351879
perf_ctrls->auto_sel = (bool)auto_sel;
18361880

18371881
out_err:

0 commit comments

Comments
 (0)