Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

irqchip/sifive-plic: Avoid interrupt ID 0 handling during suspend/resume

According to the PLIC specification[1], global interrupt sources are
assigned small unsigned integer identifiers beginning at the value 1.
An interrupt ID of 0 is reserved to mean "no interrupt".

The current plic_irq_resume() and plic_irq_suspend() functions incorrectly
start the loop from index 0, which accesses the register space for the
reserved interrupt ID 0.

Change the loop to start from index 1, skipping the reserved
interrupt ID 0 as per the PLIC specification.

This prevents potential undefined behavior when accessing the reserved
register space during suspend/resume cycles.

Fixes: e80f0b6a2cf3 ("irqchip/irq-sifive-plic: Add syscore callbacks for hibernation")
Co-developed-by: Jia Wang <wangjia@ultrarisc.com>
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
Co-developed-by: Charles Mirabile <cmirabil@redhat.com>
Signed-off-by: Charles Mirabile <cmirabil@redhat.com>
Signed-off-by: Lucas Zampieri <lzampier@redhat.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://github.com/riscv/riscv-plic-spec/releases/tag/1.0.0

authored by

Lucas Zampieri and committed by
Thomas Gleixner
f75e07bf 196754c2

+4 -2
+4 -2
drivers/irqchip/irq-sifive-plic.c
··· 254 254 255 255 priv = per_cpu_ptr(&plic_handlers, smp_processor_id())->priv; 256 256 257 - for (i = 0; i < priv->nr_irqs; i++) { 257 + /* irq ID 0 is reserved */ 258 + for (i = 1; i < priv->nr_irqs; i++) { 258 259 __assign_bit(i, priv->prio_save, 259 260 readl(priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID)); 260 261 } ··· 286 285 287 286 priv = per_cpu_ptr(&plic_handlers, smp_processor_id())->priv; 288 287 289 - for (i = 0; i < priv->nr_irqs; i++) { 288 + /* irq ID 0 is reserved */ 289 + for (i = 1; i < priv->nr_irqs; i++) { 290 290 index = BIT_WORD(i); 291 291 writel((priv->prio_save[index] & BIT_MASK(i)) ? 1 : 0, 292 292 priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID);