Skip to content

Commit 865bb6e

Browse files
NVIDIA: VR: SAUCE: 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> (backported from https://lore.kernel.org/all/20260318095005.2437960-1-sumitg@nvidia.com/) [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 17f54e0 commit 865bb6e

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
@@ -1391,35 +1391,53 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
13911391
}
13921392
}
13931393

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

1397-
cpc_read(cpunum, lowest_reg, &low);
1399+
ret = cpc_read(cpunum, lowest_reg, &low);
1400+
if (ret)
1401+
goto out_err;
13981402
perf_caps->lowest_perf = low;
13991403

1400-
cpc_read(cpunum, nominal_reg, &nom);
1404+
ret = cpc_read(cpunum, nominal_reg, &nom);
1405+
if (ret)
1406+
goto out_err;
14011407
perf_caps->nominal_perf = nom;
14021408

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

1411-
cpc_read(cpunum, lowest_non_linear_reg, &min_nonlinear);
1419+
ret = cpc_read(cpunum, lowest_non_linear_reg, &min_nonlinear);
1420+
if (ret)
1421+
goto out_err;
14121422
perf_caps->lowest_nonlinear_perf = min_nonlinear;
14131423

1414-
if (!high || !low || !nom || !min_nonlinear)
1424+
if (!high || !low || !nom || !min_nonlinear) {
14151425
ret = -EFAULT;
1426+
goto out_err;
1427+
}
14161428

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

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

14241442
perf_caps->lowest_freq = low_f;
14251443
perf_caps->nominal_freq = nom_f;
@@ -1525,18 +1543,29 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
15251543
}
15261544
}
15271545

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

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

15411570
if (!delivered || !reference || !ref_perf) {
15421571
ret = -EFAULT;
@@ -1813,24 +1842,39 @@ int cppc_get_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
18131842
}
18141843

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

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

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

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

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

18361880
out_err:

0 commit comments

Comments
 (0)