[PATCH] cpufreq/amd-pstate-ut: Fix amd_pstate_ut_check_freq failure with 'Requested CPU Min frequency' BIOS option
From: K Prateek Nayak
Date: Wed Sep 09 2026 - 06:27:40 EST
Since commit 608a76b65288 ("cpufreq/amd-pstate: Add support for the
"Requested CPU Min frequency" BIOS option"), amd-pstate driver sets
policy->min to frequency corresponding to bios_min_perf if a valid BIOS
programmed min frequency value is detected.
amd_pstate_ut_check_freq expects policy->min to always match
lowest_nonlinear_freq which does not hold true on platforms with user
configured BIOS min freq.
Update the test case to compare policy->min to bios_min_freq on
platforms that set it. Final comparison is adjusted to account for
insane values by clamping the result within the supported frequency
range.
While at it, move freq_to_perf() and perf_to_freq() helpers to internal
header to allow their use from amd-pstate-ut.
Fixes: 608a76b65288 ("cpufreq/amd-pstate: Add support for the "Requested CPU Min frequency" BIOS option")
Signed-off-by: K Prateek Nayak <kprateek.nayak@xxxxxxx>
---
drivers/cpufreq/amd-pstate-ut.c | 23 ++++++++++++++++++++++-
drivers/cpufreq/amd-pstate.c | 13 -------------
drivers/cpufreq/amd-pstate.h | 14 ++++++++++++++
3 files changed, 36 insertions(+), 14 deletions(-)
diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
index e23773680e05..c2c1a166b3a9 100644
--- a/drivers/cpufreq/amd-pstate-ut.c
+++ b/drivers/cpufreq/amd-pstate-ut.c
@@ -226,11 +226,14 @@ static int amd_pstate_ut_check_freq(u32 index)
for_each_online_cpu(cpu) {
struct cpufreq_policy *policy __free(put_cpufreq_policy) = NULL;
struct amd_cpudata *cpudata;
+ union perf_cached perf;
policy = cpufreq_cpu_get(cpu);
if (!policy)
continue;
+
cpudata = policy->driver_data;
+ perf = READ_ONCE(cpudata->perf);
if (!((policy->cpuinfo.max_freq >= cpudata->nominal_freq) &&
(cpudata->nominal_freq > cpudata->lowest_nonlinear_freq) &&
@@ -242,7 +245,25 @@ static int amd_pstate_ut_check_freq(u32 index)
return -EINVAL;
}
- if (cpudata->lowest_nonlinear_freq != policy->min) {
+ if (perf.bios_min_perf) {
+ u32 bios_min_freq = perf_to_freq(perf, cpudata->nominal_freq,
+ perf.bios_min_perf);
+
+ /*
+ * User set bios_min_freq cannot be trusted to
+ * be within the driver limits. Clamp it similar
+ * to cpufreq_verify_within_cpu_limits().
+ */
+ bios_min_freq = clamp_t(u32, bios_min_freq,
+ policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+
+ if (bios_min_freq != policy->min) {
+ pr_err("%s cpu%d bios_min_freq=%d policy_min=%d, they should be equal!\n",
+ __func__, cpu, bios_min_freq, policy->min);
+ return -EINVAL;
+ }
+ } else if (cpudata->lowest_nonlinear_freq != policy->min) {
pr_err("%s cpu%d cpudata_lowest_nonlinear_freq=%d policy_min=%d, they should be equal!\n",
__func__, cpu, cpudata->lowest_nonlinear_freq, policy->min);
return -EINVAL;
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index ea6cc072121f..a5daabc2edcd 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -145,19 +145,6 @@ static struct quirk_entry quirk_amd_7k62 = {
.lowest_freq = 550,
};
-static inline u8 freq_to_perf(union perf_cached perf, u32 nominal_freq, unsigned int freq_val)
-{
- u32 perf_val = DIV_ROUND_UP_ULL((u64)freq_val * perf.nominal_perf, nominal_freq);
-
- return (u8)clamp(perf_val, perf.lowest_perf, perf.highest_perf);
-}
-
-static inline u32 perf_to_freq(union perf_cached perf, u32 nominal_freq, u8 perf_val)
-{
- return DIV_ROUND_UP_ULL((u64)nominal_freq * perf_val,
- perf.nominal_perf);
-}
-
static int __init dmi_matched_7k62_bios_bug(const struct dmi_system_id *dmi)
{
/**
diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h
index 9f5a81976eae..578465187b7a 100644
--- a/drivers/cpufreq/amd-pstate.h
+++ b/drivers/cpufreq/amd-pstate.h
@@ -159,6 +159,20 @@ enum amd_pstate_mode {
AMD_PSTATE_GUIDED,
AMD_PSTATE_MAX,
};
+
+static inline u8 freq_to_perf(union perf_cached perf, u32 nominal_freq, unsigned int freq_val)
+{
+ u32 perf_val = DIV_ROUND_UP_ULL((u64)freq_val * perf.nominal_perf, nominal_freq);
+
+ return (u8)clamp(perf_val, perf.lowest_perf, perf.highest_perf);
+}
+
+static inline u32 perf_to_freq(union perf_cached perf, u32 nominal_freq, u8 perf_val)
+{
+ return DIV_ROUND_UP_ULL((u64)nominal_freq * perf_val,
+ perf.nominal_perf);
+}
+
const char *amd_pstate_get_mode_string(enum amd_pstate_mode mode);
int amd_pstate_get_status(void);
int amd_pstate_update_status(const char *buf, size_t size);
base-commit: d06c75c22d5c95ee27e01fedcaa07231c9bd5c88
--
2.34.1