Commit 34edd4dc authored by liwei's avatar liwei
Browse files

cpufreq/cppc: changing highest_perf to nominal_perf in cppc_cpufreq_cpu_init()

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I99VMF


CVE: NA

--------------------------------

When turning on turbo, if frequency configuration takes effect slowly,
the updated policy->cur may be equal to the frequency configured in
governor->limits(), performance governor will not adjust the frequency,
configured frequency will remain at turbo-freq.

Simplified call stack looks as follows:
cpufreq_register_driver(&cppc_cpufreq_driver)
	...
	cppc_cpufreq_cpu_init()
		cppc_get_perf_caps()
		policy->max = cppc_perf_to_khz(caps, caps->nominal_perf)
			cppc_set_perf(highest_perf) // set highest_perf
			policy->cur = cpufreq_driver->get() // if cur == policy->max
	cpufreq_init_policy()
		...
		cpufreq_start_governor() // governor: performance
			new_freq = cpufreq_driver->get() // if new_freq == policy->max
			if (policy->cur != new_freq)
			cpufreq_out_of_sync(policy, new_freq)
				...
				policy->cur = new_freq
			...
			policy->governor->limits()
				__cpufreq_driver_target(policy->max)
					if (policy->cur==target)
					// generate error, keep set highest_perf
						ret
					cppc_set_perf(target)

Fix this by changing highest_perf to nominal_perf in cppc_cpufreq_cpu_init().

Fixes: 5477fb3b ("ACPI / CPPC: Add a CPUFreq driver for use with CPPC")
Signed-off-by: default avatarliwei <liwei728@huawei.com>
parent 76dda4fa
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -307,15 +307,15 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
	if (cpu_data->perf_caps.highest_perf > cpu_data->perf_caps.nominal_perf)
		boost_supported = true;

	/* Set policy->cur to max now. The governors will adjust later. */
	/* Set policy->cur to norm now. */
	policy->cur = cppc_cpufreq_perf_to_khz(cpu_data,
					cpu_data->perf_caps.highest_perf);
	cpu_data->perf_ctrls.desired_perf = cpu_data->perf_caps.highest_perf;
					cpu_data->perf_caps.nominal_perf);
	cpu_data->perf_ctrls.desired_perf = cpu_data->perf_caps.nominal_perf;

	ret = cppc_set_perf(cpu, &cpu_data->perf_ctrls);
	if (ret)
		pr_debug("Err setting perf value:%d on CPU:%d. ret:%d\n",
				cpu_data->perf_caps.highest_perf, cpu, ret);
				cpu_data->perf_caps.nominal_perf, cpu, ret);

	return ret;
}