From 1f697414c0b4dc7895f6923bff604a310029a9f3 Mon Sep 17 00:00:00 2001 From: Lucas Zampieri Date: Tue, 23 Sep 2025 15:43:19 +0100 Subject: [PATCH] irqchip/sifive-plic: Avoid interrupt ID 0 handling during suspend/resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mainline: f75e07bf5226da640fa99a0594687c780d9bace4 From: v6.18-rc1 Severity: Moderate task: 543279 [ Upstream commit f75e07bf5226da640fa99a0594687c780d9bace4 ] 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 Signed-off-by: Jia Wang Co-developed-by: Charles Mirabile Signed-off-by: Charles Mirabile Signed-off-by: Lucas Zampieri Signed-off-by: Thomas Gleixner Link: https://github.com/riscv/riscv-plic-spec/releases/tag/1.0.0 Signed-off-by: Sasha Levin (backported from commit 030a01fbcc426b84ceecc616d36fcd29579d32a0) K2CI-Arch: None Signed-off-by: k2ci Change-Id: I61d9a31ee715310a86d0283d1068f04f19fd6a66 Reviewed-on: https://code.kylinos.cn:443/c/institute/kernel/klinux/+/129975 Reviewed-by: 刘云 --- drivers/irqchip/irq-sifive-plic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c index 08f786e657f2..f1d275a39c1d 100644 --- a/drivers/irqchip/irq-sifive-plic.c +++ b/drivers/irqchip/irq-sifive-plic.c @@ -249,7 +249,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++) if (readl(priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID)) __set_bit(i, priv->prio_save); else @@ -280,6 +281,7 @@ static void plic_irq_resume(void) priv = per_cpu_ptr(&plic_handlers, smp_processor_id())->priv; + /* 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, -- Gitee