aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorFrancesco Magazzu <postadelmaga@gmail.com>2026-09-18 15:16:18 +0200
committerLyude Paul <lyude@redhat.com>2026-09-18 14:09:00 -0400
commit866dbd17c3d5f599b9d93ea9bd5b3d6859ff8350 (patch)
tree20d74f19595c214d0aff292b15d976882c89a3f0
parentdrm/nouveau/clk: fix list cursor use after loop in nvkm_clk_ustate_update (diff)
drm/nouveau/clk: don't use the pstate cursor after the loop
nvkm_pstate_prog() walks clk->states looking for the entry at index 'pstatei' and then keeps using the list_for_each_entry cursor after the loop. This is not triggerable today: every caller clamps the index against clk->state_nr before calling, so the loop always breaks on a real entry. It is safe by virtue of what the callers happen to do, not by anything the function itself checks. Should a caller ever pass an index that is not on the list, the cursor would point at the list head rather than at a pstate, and the pstate->base.domain[] and pstate->fanspeed accesses that follow would read past it. Rather than leave that trap in place for the next caller, track whether the entry was found and return -EINVAL if it was not. No functional change. Signed-off-by: Francesco Magazzu <postadelmaga@gmail.com> Reviewed-by: Lyude Paul <lyude@redhat.com> Signed-off-by: Lyude Paul <lyude@redhat.com> Link: https://patch.msgid.link/20260918131620.405133-3-postadelmaga@gmail.com
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
index 5da82db71dde..a43246ae681f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
@@ -270,13 +270,19 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
struct nvkm_fb *fb = subdev->device->fb;
struct nvkm_pci *pci = subdev->device->pci;
struct nvkm_pstate *pstate;
+ bool found = false;
int ret, idx = 0;
list_for_each_entry(pstate, &clk->states, head) {
- if (idx++ == pstatei)
+ if (idx++ == pstatei) {
+ found = true;
break;
+ }
}
+ if (!found)
+ return -EINVAL;
+
nvkm_debug(subdev, "setting performance state %d\n", pstatei);
clk->pstate = pstatei;