summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Zampieri <lzampier@redhat.com>2025-09-23 15:43:19 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-10-19 16:34:05 +0200
commit14fd5e880a47f435c5c85df0cf377c0d80d9bece (patch)
tree26a1f2be979073ef7716a4f72051dc9476c65f67
parent47744d188004c8ddd3317129733170723bae816d (diff)
downloadlinux-14fd5e880a47f435c5c85df0cf377c0d80d9bece.tar.gz
linux-14fd5e880a47f435c5c85df0cf377c0d80d9bece.tar.bz2
linux-14fd5e880a47f435c5c85df0cf377c0d80d9bece.zip
irqchip/sifive-plic: Avoid interrupt ID 0 handling during suspend/resume
[ 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 <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 Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/irqchip/irq-sifive-plic.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index bf69a4802b71..9c4af7d58846 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -252,7 +252,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));
}
@@ -283,7 +284,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);