]> git.hungrycats.org Git - linux/commitdiff
cpufreq/amd-pstate: handle missing policy in dynamic EPP callbacks
authorEDAMAMEX <edame8080@gmail.com>
Wed, 20 May 2026 07:02:11 +0000 (16:02 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Sep 2026 11:36:16 +0000 (13:36 +0200)
[ Upstream commit 39c0cf62fc7851a17782e7efe8dfb2948739c681 ]

cpufreq_cpu_get() returns NULL when no cpufreq policy is associated with
the requested CPU, for example because the CPU is offline or the policy
has already been torn down.  Both amd_pstate_power_supply_notifier() and
amd_pstate_profile_set() acquire a policy via cpufreq_cpu_get() and then
pass that pointer to amd_pstate_get_balanced_epp() and
amd_pstate_set_epp(), which dereference it unconditionally.  A racing
CPU hotplug or driver teardown can therefore lead to a NULL pointer
dereference on either of these dynamic EPP paths.

The third cpufreq_cpu_get() caller in this file, amd_pstate_verify(),
already handles the NULL case.  Bring the two new callers in line with
that pattern: return NOTIFY_OK from the power-supply notifier (matching
the other "nothing to do" exits) and -ENODEV from amd_pstate_profile_set()
(the usual cpufreq error for a missing CPU policy).

Found by code inspection; not tested on hardware.

Fixes: e30ca6dd5345 ("cpufreq/amd-pstate: Add dynamic energy performance preference")
Fixes: 798c47593cca ("cpufreq/amd-pstate: Add support for platform profile class")
Signed-off-by: EDAMAMEX <edame8080@gmail.com>
Link: https://lore.kernel.org/r/20260520070211.2753183-1-edame8080@gmail.com
Signed-off-by: Mario Limonciello <superm1@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/cpufreq/amd-pstate.c

index 0b29213a019f505ba92d79ed3c7f74ef4063e290..627d578c7e13ab2f8ccfea2db4a0fd2cb381d6a8 100644 (file)
@@ -1113,6 +1113,9 @@ static int amd_pstate_power_supply_notifier(struct notifier_block *nb,
        if (cpudata->current_profile != PLATFORM_PROFILE_BALANCED)
                return 0;
 
+       if (!policy)
+               return NOTIFY_OK;
+
        epp = amd_pstate_get_balanced_epp(policy);
 
        ret = amd_pstate_set_epp(policy, epp);
@@ -1148,6 +1151,9 @@ static int amd_pstate_profile_set(struct device *dev,
        struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpudata->cpu);
        int ret;
 
+       if (!policy)
+               return -ENODEV;
+
        switch (profile) {
        case PLATFORM_PROFILE_LOW_POWER:
                ret = amd_pstate_set_epp(policy, AMD_CPPC_EPP_POWERSAVE);