From: Aboorva Devarajan <aboorvad@linux.ibm.com>
To: rafael@kernel.org, christian.loehle@arm.com, daniel.lezcano@linaro.org
Cc: aboorvad@linux.ibm.com, linux-pm@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH] cpuidle: ladder: Fix state index when only one idle state is registered
Date: Wed, 11 Feb 2026 11:05:52 +0530 [thread overview]
Message-ID: <20260211053552.739337-1-aboorvad@linux.ibm.com> (raw)
On certain platforms (PowerNV systems without a power-mgt DT node),
cpuidle may register only a single idle state. In cases where that
single state is a polling state (state 0), the ladder governor may
incorrectly treat state 1 as the first usable state and pass an
out-of-bounds index. This can lead to a NULL enter callback being
invoked, ultimately resulting in a system crash.
[ 13.342636] cpuidle-powernv : Only Snooze is available
[ 13.351854] Faulting instruction address: 0x00000000
[ 13.376489] NIP [0000000000000000] 0x0
[ 13.378351] LR [c000000001e01974] cpuidle_enter_state+0x2c4/0x668
Fix this by determining the first non-polling state index based on
the number of registered states, and by returning state 0 when only
one state is registered.
Fixes: dc2251bf98c6 ("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol")
Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
---
drivers/cpuidle/governors/ladder.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c
index 6617eb494a11..294a688ed0bb 100644
--- a/drivers/cpuidle/governors/ladder.c
+++ b/drivers/cpuidle/governors/ladder.c
@@ -42,6 +42,21 @@ struct ladder_device {
static DEFINE_PER_CPU(struct ladder_device, ladder_devices);
+/**
+ * ladder_get_first_idx - get the first non-polling state index
+ * @drv: cpuidle driver
+ *
+ * Returns the index of the first non-polling state, or 0 if state 0 is not
+ * polling or if there's only one state available.
+ */
+static inline int ladder_get_first_idx(struct cpuidle_driver *drv)
+{
+ if (drv->state_count > 1 &&
+ drv->states[0].flags & CPUIDLE_FLAG_POLLING)
+ return 1;
+ return 0;
+}
+
/**
* ladder_do_selection - prepares private data for a state change
* @dev: the CPU
@@ -70,16 +85,17 @@ static int ladder_select_state(struct cpuidle_driver *drv,
struct ladder_device *ldev = this_cpu_ptr(&ladder_devices);
struct ladder_device_state *last_state;
int last_idx = dev->last_state_idx;
- int first_idx = drv->states[0].flags & CPUIDLE_FLAG_POLLING ? 1 : 0;
+ int first_idx;
s64 latency_req = cpuidle_governor_latency_req(dev->cpu);
s64 last_residency;
- /* Special case when user has set very strict latency requirement */
- if (unlikely(latency_req == 0)) {
+ /* Special case when there's only one state or strict latency requirement */
+ if (unlikely(drv->state_count <= 1 || latency_req == 0)) {
ladder_do_selection(dev, ldev, last_idx, 0);
return 0;
}
+ first_idx = ladder_get_first_idx(drv);
last_state = &ldev->states[last_idx];
last_residency = dev->last_residency_ns - drv->states[last_idx].exit_latency_ns;
@@ -134,7 +150,7 @@ static int ladder_enable_device(struct cpuidle_driver *drv,
struct cpuidle_device *dev)
{
int i;
- int first_idx = drv->states[0].flags & CPUIDLE_FLAG_POLLING ? 1 : 0;
+ int first_idx = ladder_get_first_idx(drv);
struct ladder_device *ldev = &per_cpu(ladder_devices, dev->cpu);
struct ladder_device_state *lstate;
struct cpuidle_state *state;
--
2.52.0
next reply other threads:[~2026-02-11 5:36 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-11 5:35 Aboorva Devarajan [this message]
2026-02-11 15:00 ` [PATCH] cpuidle: ladder: Fix state index when only one idle state is registered Christian Loehle
2026-02-13 8:29 ` Aboorva Devarajan
2026-02-13 13:44 ` Christian Loehle
2026-02-16 11:05 ` Christian Loehle
2026-02-16 18:58 ` Aboorva Devarajan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260211053552.739337-1-aboorvad@linux.ibm.com \
--to=aboorvad@linux.ibm.com \
--cc=christian.loehle@arm.com \
--cc=daniel.lezcano@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=rafael@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox