]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
cpufreq: intel_pstate: Fix crash during turbo disable
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Wed, 25 Feb 2026 00:17:52 +0000 (16:17 -0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 25 Feb 2026 13:39:19 +0000 (14:39 +0100)
When the system is booted with kernel command line argument "nosmt" or
"maxcpus" to limit the number of CPUs, disabling turbo via:

 echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo

results in a crash:

 PF: supervisor read access in kernel mode
 PF: error_code(0x0000) - not-present page
 PGD 0 P4D 0
 Oops: Oops: 0000 [#1] SMP PTI
 ...
 RIP: 0010:store_no_turbo+0x100/0x1f0
 ...

This occurs because for_each_possible_cpu() returns CPUs even if they
are not online. For those CPUs, all_cpu_data[] will be NULL. Since
commit 973207ae3d7c ("cpufreq: intel_pstate: Rearrange max frequency
updates handling code"), all_cpu_data[] is dereferenced even for CPUs
which are not online, causing the NULL pointer dereference.

To fix that, pass CPU number to intel_pstate_update_max_freq() and use
all_cpu_data[] for those CPUs for which there is a valid cpufreq policy.

Fixes: 973207ae3d7c ("cpufreq: intel_pstate: Rearrange max frequency updates handling code")
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221068
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Cc: 6.16+ <stable@vger.kernel.org> # 6.16+
Link: https://patch.msgid.link/20260225001752.890164-1-srinivas.pandruvada@linux.intel.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/cpufreq/intel_pstate.c

index bdc37080d319ed567dd22220fe769edbbc35547f..11c58af41900645154938618caf9bc66d8bb5a23 100644 (file)
@@ -1476,13 +1476,13 @@ static void __intel_pstate_update_max_freq(struct cpufreq_policy *policy,
        refresh_frequency_limits(policy);
 }
 
-static bool intel_pstate_update_max_freq(struct cpudata *cpudata)
+static bool intel_pstate_update_max_freq(int cpu)
 {
-       struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpudata->cpu);
+       struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpu);
        if (!policy)
                return false;
 
-       __intel_pstate_update_max_freq(policy, cpudata);
+       __intel_pstate_update_max_freq(policy, all_cpu_data[cpu]);
 
        return true;
 }
@@ -1501,7 +1501,7 @@ static void intel_pstate_update_limits_for_all(void)
        int cpu;
 
        for_each_possible_cpu(cpu)
-               intel_pstate_update_max_freq(all_cpu_data[cpu]);
+               intel_pstate_update_max_freq(cpu);
 
        mutex_lock(&hybrid_capacity_lock);
 
@@ -1910,7 +1910,7 @@ static void intel_pstate_notify_work(struct work_struct *work)
        struct cpudata *cpudata =
                container_of(to_delayed_work(work), struct cpudata, hwp_notify_work);
 
-       if (intel_pstate_update_max_freq(cpudata)) {
+       if (intel_pstate_update_max_freq(cpudata->cpu)) {
                /*
                 * The driver will not be unregistered while this function is
                 * running, so update the capacity without acquiring the driver