sh: intc: Sort the prio and sense lists after filling them

register_intc_controller() sorts d->prio and d->sense right after
allocating them, with hw->nr_prio_regs and hw->nr_sense_regs as the
element count. The lists hold hw->nr_vectors entries and are only
filled later, by intc_register_irq().

On SH7785, sh7785-irq0123 and sh7785-irq4567 have four vectors but the
SoC's eleven priority registers, so sort() swaps 88 bytes in a 32 byte
kmalloc object at boot. slub_debug=FZPU reports "Right Redzone
overwritten" in kmalloc-32, and v6.5 and v6.6 panic in
__kmem_cache_alloc_node() while registering sh7785-irq0123.

Found with a custom QEMU model of the SH7785LCR. On it, v6.4
sh7785lcr_defconfig boots with SLAB, the defconfig default before v6.5,
and hangs before the console is up when built with SLUB.

Sort the lists once all vectors are registered, with the number of
entries that were added.

Fixes: b59f9f9775 ("sh: intc: optimize intc IRQ lookup")
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Assisted-by: LLM
Cc: stable@vger.kernel.org
Tested-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Reviewed-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
This commit is contained in:
Karl Mehltretter 2026-09-27 21:13:59 +02:00 committed by John Paul Adrian Glaubitz
parent 9b65dcd942
commit 94a219eda3

View File

@ -275,9 +275,6 @@ int __init register_intc_controller(struct intc_desc *desc)
k += save_reg(d, k, hw->prio_regs[i].set_reg, smp);
k += save_reg(d, k, hw->prio_regs[i].clr_reg, smp);
}
sort(d->prio, hw->nr_prio_regs, sizeof(*d->prio),
intc_handle_int_cmp, NULL);
}
if (hw->sense_regs) {
@ -287,9 +284,6 @@ int __init register_intc_controller(struct intc_desc *desc)
for (i = 0; i < hw->nr_sense_regs; i++)
k += save_reg(d, k, hw->sense_regs[i].reg, 0);
sort(d->sense, hw->nr_sense_regs, sizeof(*d->sense),
intc_handle_int_cmp, NULL);
}
if (hw->subgroups)
@ -357,6 +351,11 @@ int __init register_intc_controller(struct intc_desc *desc)
}
}
sort(d->prio, d->nr_prio, sizeof(*d->prio),
intc_handle_int_cmp, NULL);
sort(d->sense, d->nr_sense, sizeof(*d->sense),
intc_handle_int_cmp, NULL);
intc_subgroup_init(desc, d);
/* enable bits matching force_enable after registering irqs */