From 0ffc7534a210105ba973167a5b86d5ab39d4031f Mon Sep 17 00:00:00 2001 From: Tristan Madani Date: Mon, 19 Oct 2026 22:26:35 +0000 Subject: cpufreq: intel_pstate: cancel HWP notify work in driver cleanup intel_pstate_driver_cleanup() frees per-CPU data without cancelling the pending HWP notify delayed work. If hwp_notify_work is still scheduled or running when the struct is freed, the work function accesses freed memory via container_of(). Call intel_pstate_disable_hwp_interrupt() before kfree() to disable the interrupt source and cancel the pending work, matching the pattern used in intel_pstate_suspend() and intel_pstate_hwp_offline(). Fixes: d845cd901b28 ("cpufreq: intel_pstate: Support highest performance change interrupt") Cc: All applicable Signed-off-by: Tristan Madani [ rjw: Fixed the Fixes: tag ] Link: https://patch.msgid.link/20261019222635.1741146-1-tristmd@gmail.com Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/intel_pstate.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 17158cb25dd8..0e6ae4cdda5d 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -3436,6 +3436,8 @@ static void intel_pstate_driver_cleanup(void) if (intel_pstate_driver == &intel_pstate) intel_pstate_clear_update_util_hook(cpu); + intel_pstate_disable_hwp_interrupt(all_cpu_data[cpu]); + kfree(all_cpu_data[cpu]); WRITE_ONCE(all_cpu_data[cpu], NULL); } -- cgit v1.2.3 From 6c7a7007c5b7566fba4fbee1d40011fb8f833dc3 Mon Sep 17 00:00:00 2001 From: Karl Mehltretter Date: Thu, 10 Sep 2026 22:52:34 +0200 Subject: PM: EM: allocate the cpumask for every perf domain em_create_pd() allocates space for the trailing cpus[] flexible array only for CPU devices. A performance domain registered for another device therefore has no storage for its cpumask. All performance domains are added to em_pd_list. The netlink interface does not distinguish CPU and non-CPU domains when it calls cpumask_weight() or iterates over pd->cpus. A request for a non-CPU domain reads cpumask_size() bytes beyond the allocation and can report bits from the following memory as CPU attributes. KASAN reports slab-out-of-bounds reads for both dump and by-ID requests against a synthetic non-CPU performance domain. GET_PERF_DOMAINS does not require GENL_ADMIN_PERM, so an unprivileged request can reach this path when a GPU or another devfreq device has registered an energy model. Allocate the cpumask for non-CPU domains too. The zeroed mask remains empty, as required for the documented unused field. Fixes: d8eef0453132 ("PM: EM: Implement em_nl_get_pds_doit()") Cc: All Applicable Signed-off-by: Karl Mehltretter Reviewed-by: Lukasz Luba Link: https://patch.msgid.link/20260910205234.5392-1-kmehltretter@gmail.com Signed-off-by: Rafael J. Wysocki --- kernel/power/energy_model.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c index a76089e2ce8c..d19a65461ae8 100644 --- a/kernel/power/energy_model.c +++ b/kernel/power/energy_model.c @@ -439,7 +439,9 @@ static int em_create_pd(struct device *dev, int nr_states, cpumask_copy(em_span_cpus(pd), cpus); } else { - pd = kzalloc_obj(*pd); + /* Readers expect pd->cpus to exist and remain empty. */ + pd = kzalloc_flex(*pd, cpus, + BITS_TO_LONGS(large_cpumask_bits)); if (!pd) return -ENOMEM; } -- cgit v1.2.3 From 4035247966859152a6523bc041f81cb9905695a5 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 21 Oct 2026 17:56:08 +0200 Subject: intel_idle: Adjust state names and descriptions for _LPI states The value of the _LPI "State Name" field is used as the description of the given idle state (that is, the value of its "desc" attribute in sysfs) which is not consistent with idle state descriptions used when the idle state information comes from an ACPI _CST object. To rectify that, use the _LPI "State Name" field value as the value of the "name" sysfs attribute of a given idle state and use the MWAIT hint value from the _LPI register address value to derive the value of its "desc" sysfs attribute in analogy with the _CST case. Fixes: abc5c103c66d ("intel_idle: Add ACPI _LPI support") Tested-by: Len Brown Cc: 7.3+ # 7.3+ Signed-off-by: Rafael J. Wysocki [ rjw: Adjusted scnprintf() format string, tweaked changelog ] Link: https://patch.msgid.link/6061409.DvuYhMxLoT@rafael.j.wysocki Signed-off-by: Rafael J. Wysocki --- Documentation/admin-guide/pm/intel_idle.rst | 12 +++++++----- drivers/idle/intel_idle.c | 9 +++++++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Documentation/admin-guide/pm/intel_idle.rst b/Documentation/admin-guide/pm/intel_idle.rst index 996e5bd83c42..d1a6251790b8 100644 --- a/Documentation/admin-guide/pm/intel_idle.rst +++ b/Documentation/admin-guide/pm/intel_idle.rst @@ -145,11 +145,13 @@ for the other idle state types (C2 and C3) the target residency value is 3 times the exit latency (again, that is because it reflects the target residency to exit latency ratio in the majority of cases for the processor models recognized by ``intel_idle``). The name of the idle state (to be returned by the ``name`` -idle state attribute in ``sysfs``) is either "Cx_LPI" (if it comes from ``_LPI`` -processing) or "Cx_ACPI", where x is the index of that idle state in the final -list (note that the minimum value of x is 1, because 0 is reserved for the -"polling" state), and its target residency is based on the exit latency value. -All of the idle states in the final list are enabled by default in this case. +idle state attribute in ``sysfs``) either is equal to the state name value that +comes from ``_LPI`` processing (with the possible fallback to "Cx_LPI" if the +state name is not provided) or it is "Cx_ACPI", where x is the index of that +idle state in the final list (note that the minimum value of x is 1, because 0 +is reserved for the "polling" state), and its target residency is based on the +exit latency value. All of the idle states in the final list are enabled by +default in this case. .. _intel-idle-initialization: diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index a045a384b949..9f5e1c47aba2 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -1903,8 +1903,13 @@ static void __init intel_idle_init_cstates_acpi_lpi(struct cpuidle_driver *drv) state = &drv->states[drv->state_count++]; - scnprintf(state->name, CPUIDLE_NAME_LEN, "C%d_LPI", index + 1); - strscpy(state->desc, lpi_state->desc); + if (strlen(lpi_state->desc) > 0) + strscpy(state->name, lpi_state->desc); + else + scnprintf(state->name, CPUIDLE_NAME_LEN, "C%d_LPI", index + 1); + + scnprintf(state->desc, CPUIDLE_DESC_LEN, "ACPI LPI MWAIT 0x%02llx", + lpi_state->address); state->exit_latency = lpi_state->wake_latency; state->target_residency = lpi_state->min_residency; state->flags = MWAIT2flg(lpi_state->address); -- cgit v1.2.3 From 4785d5faa935a828a04743c5a7d279baf454c723 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Mon, 5 Oct 2026 11:11:57 +0000 Subject: PM: suspend: Do not call suspend_ops->begin()/end() for s2idle Commit 7602c0ec0bbf ("firmware: psci: Set pm_set_resume/suspend_via_firmware() for SYSTEM_SUSPEND") made psci_system_suspend_begin() call pm_set_suspend_via_firmware(), so that device drivers can prepare for the possible removal of the power before PSCI SYSTEM_SUSPEND. Since then, on platforms where PSCI firmware supports SYSTEM_SUSPEND, pm_suspend_via_firmware() returns true during both s2ram and s2idle. This is inconsistent, since SYSTEM_SUSPEND is only invoked for s2ram. This was observed while investigating PCI-related suspend/resume issues on Renesas platforms (RZ/G3S, RZ/V2H), and was traced to platform_suspend_begin() falling back to suspend_ops->begin() (PSCI in this case) when there is no s2idle_ops->begin() callback: platform_suspend_begin(PM_SUSPEND_TO_IDLE) suspend_ops->begin() psci_system_suspend_begin() pm_set_suspend_via_firmware() platform_resume_end() falls back to suspend_ops->end() in the same way. Since s2idle has its own set of callbacks in s2idle_ops, make platform_suspend_begin() and platform_resume_end() only invoke those for s2idle, like the other platform_*() helpers do. Fixes: 7602c0ec0bbf ("firmware: psci: Set pm_set_resume/suspend_via_firmware() for SYSTEM_SUSPEND") Signed-off-by: Ovidiu Panait Tested-by: Claudiu Beznea Link: https://patch.msgid.link/20261005111157.17256-1-ovidiu.panait.rb@renesas.com [ rjw: Added Fixes: tag ] Signed-off-by: Rafael J. Wysocki --- kernel/power/suspend.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 57c44268698f..32c055df02da 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -306,20 +306,24 @@ static void platform_resume_finish(suspend_state_t state) static int platform_suspend_begin(suspend_state_t state) { - if (state == PM_SUSPEND_TO_IDLE && s2idle_ops && s2idle_ops->begin) - return s2idle_ops->begin(); - else if (suspend_ops && suspend_ops->begin) + if (state == PM_SUSPEND_TO_IDLE) { + if (s2idle_ops && s2idle_ops->begin) + return s2idle_ops->begin(); + } else if (suspend_ops && suspend_ops->begin) { return suspend_ops->begin(state); - else - return 0; + } + + return 0; } static void platform_resume_end(suspend_state_t state) { - if (state == PM_SUSPEND_TO_IDLE && s2idle_ops && s2idle_ops->end) - s2idle_ops->end(); - else if (suspend_ops && suspend_ops->end) + if (state == PM_SUSPEND_TO_IDLE) { + if (s2idle_ops && s2idle_ops->end) + s2idle_ops->end(); + } else if (suspend_ops && suspend_ops->end) { suspend_ops->end(); + } } static void platform_recover(suspend_state_t state) -- cgit v1.2.3 From 8a702989677216489e471a6f27599da53f753567 Mon Sep 17 00:00:00 2001 From: Zhongqiu Han Date: Tue, 27 Oct 2026 21:33:31 +0800 Subject: cpufreq: stats: Fix potential out-of-bounds access in deferred reset cpufreq_stats_create_table() sets stats->last_index to -1 if policy->cur is not in the frequency table. It then stays at -1, because cpufreq_stats_record_transition() returns early on old_index == -1 before it gets to update last_index. Commit 46a310b80bc2 ("[CPUFREQ] Don't set stat->last_index to -1 if the pol->cur has incorrect value.") added that check. However, since commit 40c3bd4cfa6f ("cpufreq: stats: Defer stats update to cpufreq_stats_record_transition()"), the stats reset is deferred to the beginning of cpufreq_stats_record_transition(), before that check, and cpufreq_stats_reset_table() ends with an unconditional cpufreq_stats_update(). So if the "reset" attribute is written while last_index is -1, the next frequency transition accesses time_in_state[-1]. Fix it by also returning early on last_index == -1 in cpufreq_stats_reset_table(). Fixes: 40c3bd4cfa6f ("cpufreq: stats: Defer stats update to cpufreq_stats_record_transition()") Cc: 5.10+ # 5.10+ Signed-off-by: Zhongqiu Han Link: https://patch.msgid.link/20261027133332.377546-1-zhongqiu.han@oss.qualcomm.com Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq_stats.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 670a10c3ecfa..e7ec16bcb67e 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -52,6 +52,10 @@ static void cpufreq_stats_reset_table(struct cpufreq_stats *stats) * reset_pending accesses in cpufreq_stats_record_transition(). */ smp_rmb(); + + if (stats->last_index == -1) + return; + cpufreq_stats_update(stats, READ_ONCE(stats->reset_time)); } -- cgit v1.2.3 From 1faca2d1ed7d28f4156690cda43a9814e22b4460 Mon Sep 17 00:00:00 2001 From: Joshua Crofts Date: Tue, 27 Oct 2026 12:20:42 +0000 Subject: PM: runtime: clarify pm_runtime_use_autosuspend() undo mechanism Commit d1706f9da9f4 ("PM: runtime: call pm_runtime_dont_use_autosuspend() on reinit()") introduced a pm_runtime_dont_use_autosuspend() call that is executed automatically on driver exit without making any changes to the kerneldocs. Update the kerneldocs to clarify the current mechanism of pm_runtime_use_autosuspend() cleanup on exit. Fixes: d1706f9da9f4 ("PM: runtime: call pm_runtime_dont_use_autosuspend() on reinit()") Signed-off-by: Joshua Crofts [ rjw: Added Fixes: tag ] Link: https://patch.msgid.link/20261027122042.1444-1-crofts@kernel.org Signed-off-by: Rafael J. Wysocki --- Documentation/power/runtime_pm.rst | 10 +++++----- include/linux/pm_runtime.h | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Documentation/power/runtime_pm.rst b/Documentation/power/runtime_pm.rst index e4407b687f8b..40a5c23d5259 100644 --- a/Documentation/power/runtime_pm.rst +++ b/Documentation/power/runtime_pm.rst @@ -425,11 +425,11 @@ but it also allows more flexibility in the handling of devices during the removal of their drivers. Drivers in ->remove() callback should undo the runtime PM changes done -in ->probe(). Usually this means calling pm_runtime_disable(), -pm_runtime_dont_use_autosuspend() etc. Alternatively, drivers can use -devm_pm_runtime_enable() during probe, which automatically takes care of -calling pm_runtime_disable() and pm_runtime_dont_use_autosuspend() upon driver -detachment. +in ->probe(). Usually this means calling pm_runtime_disable() etc. +Alternatively, drivers can use devm_pm_runtime_enable() during probe, which +automatically takes care of calling pm_runtime_disable() upon driver detachment. +Any pm_runtime_use_autosuspend() calls in a driver will be automatically undone +on driver exit. The user space can effectively disallow the driver of the device to power manage it at run time by changing the value of its /sys/devices/.../power/control diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 322e3b17f987..ae68a9dc7fc5 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -855,9 +855,9 @@ static inline void pm_runtime_disable(struct device *dev) * requested (or "autosuspend" will be handled as direct runtime-suspend for * it). * - * NOTE: It's important to undo this with pm_runtime_dont_use_autosuspend() - * at driver exit time unless your driver initially enabled pm_runtime - * with devm_pm_runtime_enable() (which handles it for you). + * NOTE: This is undone automatically with pm_runtime_dont_use_autosuspend() on + * driver exit regardless of whether a driver uses managed devm_* functions or + * not. */ static inline void pm_runtime_use_autosuspend(struct device *dev) { -- cgit v1.2.3