]> www.infradead.org Git - users/hch/misc.git/commitdiff
irqchip/sifive-plic: Avoid interrupt ID 0 handling during suspend/resume
authorLucas Zampieri <lzampier@redhat.com>
Tue, 23 Sep 2025 14:43:19 +0000 (15:43 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Tue, 7 Oct 2025 08:23:22 +0000 (10:23 +0200)
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
drivers/irqchip/irq-sifive-plic.c

index 559fda8fb3a86a71d8041bf88558f9a39faecf9b..cbd7697bc14819cbe3b77096b26901b605491f75 100644 (file)
@@ -254,7 +254,8 @@ static int plic_irq_suspend(void)
 
        priv = per_cpu_ptr(&plic_handlers, smp_processor_id())->priv;
 
-       for (i = 0; i < priv->nr_irqs; i++) {
+       /* irq ID 0 is reserved */
+       for (i = 1; i < priv->nr_irqs; i++) {
                __assign_bit(i, priv->prio_save,
                             readl(priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID));
        }
@@ -285,7 +286,8 @@ static void plic_irq_resume(void)
 
        priv = per_cpu_ptr(&plic_handlers, smp_processor_id())->priv;
 
-       for (i = 0; i < priv->nr_irqs; i++) {
+       /* irq ID 0 is reserved */
+       for (i = 1; i < priv->nr_irqs; i++) {
                index = BIT_WORD(i);
                writel((priv->prio_save[index] & BIT_MASK(i)) ? 1 : 0,
                       priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID);