drivers/cpufreq/amd-pstate-ut.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
Dan reported a possible NULL pointer dereference in amd-pstate-ut.c from
static analysis and sure enough, running amd-pstate-ut in active mode
with amd_dynamic_epp=enable results in a crash as a reult of the policy
reference being set to NULL early, before disabling dynamic EPP.
Kalpana also reported seeing amd-pstate-ut error out with -EBUSY for
"amd_pstate_ut_epp" test when starting from the passive mode and
amd_dynamic_epp=enable in the command line. The reason for the failure
is that the command line enables dynamic_epp by default after the mode
switch and the modifications to EPP values are blocked when running in
dynamic EPP mode.
Solution to both problems is to toggle off dynamic_epp *after* the mode
switch when the driver grabs the policy reference again since the unit
test is in full control of the policy after that point.
The final restoration step will reset the dynamic_epp state via mode
switch based on the initial conditions of the system.
Reported-by: Kalpana Shetty <kalpana.shetty@amd.com>
Reported-by: Dan Carpenter <error27@gmail.com>
Closes: https://lore.kernel.org/linux-pm/ahEq0CvdBX0T7_cO@stanley.mountain/
Fixes: f9f16835d4dc ("cpufreq/amd-pstate-ut: Drop policy reference before driver switch")
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
Patches are based on:
git.kernel.org/pub/scm/linux/kernel/git/superm1/linux.git amd-pstate-fixes
Sorry for the oversight on f9f16835d4dc. I've tested the fix
exhaustively this time around on a Zen4 system with all combinations of
driver modes and amd_dynamic_epp state and the unit test runs
successfully under all combinations without any errors.
---
drivers/cpufreq/amd-pstate-ut.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
index 13a23dac477d..735b29f76438 100644
--- a/drivers/cpufreq/amd-pstate-ut.c
+++ b/drivers/cpufreq/amd-pstate-ut.c
@@ -302,12 +302,6 @@ static int amd_pstate_ut_epp(u32 index)
cpufreq_cpu_put(policy);
policy = NULL;
- /* disable dynamic EPP before running test */
- if (cpudata->dynamic_epp) {
- pr_debug("Dynamic EPP is enabled, disabling it\n");
- amd_pstate_clear_dynamic_epp(policy);
- }
-
buf = (char *)__get_free_page(GFP_KERNEL);
if (!buf)
return -ENOMEM;
@@ -327,6 +321,16 @@ static int amd_pstate_ut_epp(u32 index)
orig_policy = cpudata->policy;
cpudata->policy = CPUFREQ_POLICY_POWERSAVE;
+ /*
+ * Disable dynamic EPP before running test. If "orig_dynamic_epp" is
+ * true, the driver will do a redundant switch at the end and there
+ * is no need for enabling it again at the end of the test.
+ */
+ if (cpudata->dynamic_epp) {
+ pr_debug("Dynamic EPP is enabled, disabling it\n");
+ amd_pstate_clear_dynamic_epp(policy);
+ }
+
for (epp = 0; epp <= U8_MAX; epp++) {
u8 val;
base-commit: e4e9b7b38d5db2cc6a8770bc0596bb8b36b92b1f
--
2.34.1
© 2016 - 2026 Red Hat, Inc.