Skip to content

Commit 6fa12d5

Browse files
Prashanth Prakashrafaeljw
authored andcommitted
ACPI / CPPC: Check for valid PCC subspace only if PCC is used
Changes the behavior where we return error if there are no valid PCC subspace for a given performance domain. The ACPI spec does not mandate the use PCC, so it is possible to have platforms where a PCC subspace may not be present, so we need to check for a valid PCC subspace ID only if the register is a PCC register. Signed-off-by: Prashanth Prakash <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 4773e77 commit 6fa12d5

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

drivers/acpi/cppc_acpi.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,15 +1075,14 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
10751075
*low_freq_reg = NULL, *nom_freq_reg = NULL;
10761076
u64 high, low, nom, min_nonlinear, low_f = 0, nom_f = 0;
10771077
int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum);
1078-
struct cppc_pcc_data *pcc_ss_data;
1078+
struct cppc_pcc_data *pcc_ss_data = NULL;
10791079
int ret = 0, regs_in_pcc = 0;
10801080

1081-
if (!cpc_desc || pcc_ss_id < 0) {
1081+
if (!cpc_desc) {
10821082
pr_debug("No CPC descriptor for CPU:%d\n", cpunum);
10831083
return -ENODEV;
10841084
}
10851085

1086-
pcc_ss_data = pcc_data[pcc_ss_id];
10871086
highest_reg = &cpc_desc->cpc_regs[HIGHEST_PERF];
10881087
lowest_reg = &cpc_desc->cpc_regs[LOWEST_PERF];
10891088
lowest_non_linear_reg = &cpc_desc->cpc_regs[LOW_NON_LINEAR_PERF];
@@ -1095,6 +1094,11 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
10951094
if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) ||
10961095
CPC_IN_PCC(lowest_non_linear_reg) || CPC_IN_PCC(nominal_reg) ||
10971096
CPC_IN_PCC(low_freq_reg) || CPC_IN_PCC(nom_freq_reg)) {
1097+
if (pcc_ss_id < 0) {
1098+
pr_debug("Invalid pcc_ss_id\n");
1099+
return -ENODEV;
1100+
}
1101+
pcc_ss_data = pcc_data[pcc_ss_id];
10981102
regs_in_pcc = 1;
10991103
down_write(&pcc_ss_data->pcc_lock);
11001104
/* Ring doorbell once to update PCC subspace */
@@ -1150,16 +1154,15 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
11501154
struct cpc_register_resource *delivered_reg, *reference_reg,
11511155
*ref_perf_reg, *ctr_wrap_reg;
11521156
int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum);
1153-
struct cppc_pcc_data *pcc_ss_data;
1157+
struct cppc_pcc_data *pcc_ss_data = NULL;
11541158
u64 delivered, reference, ref_perf, ctr_wrap_time;
11551159
int ret = 0, regs_in_pcc = 0;
11561160

1157-
if (!cpc_desc || pcc_ss_id < 0) {
1161+
if (!cpc_desc) {
11581162
pr_debug("No CPC descriptor for CPU:%d\n", cpunum);
11591163
return -ENODEV;
11601164
}
11611165

1162-
pcc_ss_data = pcc_data[pcc_ss_id];
11631166
delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR];
11641167
reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR];
11651168
ref_perf_reg = &cpc_desc->cpc_regs[REFERENCE_PERF];
@@ -1175,6 +1178,11 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
11751178
/* Are any of the regs PCC ?*/
11761179
if (CPC_IN_PCC(delivered_reg) || CPC_IN_PCC(reference_reg) ||
11771180
CPC_IN_PCC(ctr_wrap_reg) || CPC_IN_PCC(ref_perf_reg)) {
1181+
if (pcc_ss_id < 0) {
1182+
pr_debug("Invalid pcc_ss_id\n");
1183+
return -ENODEV;
1184+
}
1185+
pcc_ss_data = pcc_data[pcc_ss_id];
11781186
down_write(&pcc_ss_data->pcc_lock);
11791187
regs_in_pcc = 1;
11801188
/* Ring doorbell once to update PCC subspace */
@@ -1225,15 +1233,14 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
12251233
struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
12261234
struct cpc_register_resource *desired_reg;
12271235
int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
1228-
struct cppc_pcc_data *pcc_ss_data;
1236+
struct cppc_pcc_data *pcc_ss_data = NULL;
12291237
int ret = 0;
12301238

1231-
if (!cpc_desc || pcc_ss_id < 0) {
1239+
if (!cpc_desc) {
12321240
pr_debug("No CPC descriptor for CPU:%d\n", cpu);
12331241
return -ENODEV;
12341242
}
12351243

1236-
pcc_ss_data = pcc_data[pcc_ss_id];
12371244
desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF];
12381245

12391246
/*
@@ -1244,6 +1251,11 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
12441251
* achieve that goal here
12451252
*/
12461253
if (CPC_IN_PCC(desired_reg)) {
1254+
if (pcc_ss_id < 0) {
1255+
pr_debug("Invalid pcc_ss_id\n");
1256+
return -ENODEV;
1257+
}
1258+
pcc_ss_data = pcc_data[pcc_ss_id];
12471259
down_read(&pcc_ss_data->pcc_lock); /* BEGIN Phase-I */
12481260
if (pcc_ss_data->platform_owns_pcc) {
12491261
ret = check_pcc_chan(pcc_ss_id, false);

0 commit comments

Comments
 (0)