From nobody Sun Feb 8 15:25:37 2026 Received: from out162-62-57-49.mail.qq.com (out162-62-57-49.mail.qq.com [162.62.57.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2773433EAF9 for ; Wed, 21 Jan 2026 05:45:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=162.62.57.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768974366; cv=none; b=TWe5xep9jQ0xnfeWAndHK8ep8AP7NZ64H+rxRjF5tffoSmgVNb7hNdoCa9cs3YSx1j+Jq6dzhVLoBpTMJmYJY/vWAmYip0zh2ZxdAai7fm3tZ5k+1dt8WvJ5jTzlRJmhj6G9Ec0X/RRZPku7hyMH89H0n9Hv6WwZ8lX7Wb/R9NI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768974366; c=relaxed/simple; bh=m+ppKxlH7bJrbNCJHWUWkjiGDqQnJUxsTDpDkSG3uFo=; h=Message-ID:From:To:Cc:Subject:Date:MIME-Version; b=W4x6LEFwBTuap/07N8cKPjTBKjz8DXtbRr3NYlvCWvZoM38C5/VP+rqc8Dj8LPqMntF/d3mZTEWdkun4NZjLiJ8btbPZ+VckrfL6v0Qi375wbSQVjNH4UIdCM2F5ZlCiVP8zes1YeNOcC1XkvuFGlXALQuuyGk/LB9sRmRQojok= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=cyyself.name; spf=pass smtp.mailfrom=cyyself.name; dkim=pass (1024-bit key) header.d=qq.com header.i=@qq.com header.b=ygGnTWCf; arc=none smtp.client-ip=162.62.57.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=cyyself.name Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=cyyself.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=qq.com header.i=@qq.com header.b="ygGnTWCf" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qq.com; s=s201512; t=1768974344; bh=2hfAdrr6Ey5DyT/MRw7XElyPJvDe8wPUBa8s2u/6NnM=; h=From:To:Cc:Subject:Date; b=ygGnTWCfcImv06QmhsyP6n2vs1sQda8e3dKfz+KMdMuTHTYi799GmTLWkvNV5+AVH WwtcbmmRFbb+2hLKzG+fPnXSTI0cNjqdMC4ElNm4+npAWP50l8ZUNKJI9vNCstrt8n 74e5N9I0vj1vx0wV+O3swJzChYK1V/Uwm5X8BXRk= Received: from cyy-pc.lan ([240e:379:2268:a400:43ad:678c:aeb3:355d]) by newxmesmtplogicsvrszc43-0.qq.com (NewEsmtp) with SMTP id B6898CAC; Wed, 21 Jan 2026 13:45:40 +0800 X-QQ-mid: xmsmtpt1768974340t77ckc9c4 Message-ID: X-QQ-XMAILINFO: MRMtjO3A6C9XTS8vhvmawojs2BQVngzqTotK+QHmdsr2PLG21iw9vmyDJhIEFd bkWg/G3wSW3HrbsDFH6cyhO7d9ZJeWvRhsWa8n9NIGQuPqeqzWGuLXoe9PkaujxE6cGdFHAfLAh5 J6SJf5ivp9uAAEWufIX10Eq/qb3NeOMH3usomK+SRVt7oniSpdaj0z9EbrphitjiWJSfjH/DEQmk N49bu4+JRb4jh1RmxvtIUiTiGkQfcvJ9BJ9rVB/QlwrgLaDXkckG0vIsDE3I5Lo8cF2xFymuzg7p dtNEbPAkZHhiK6jLpBPniyepET9bPS4UegOUeYaWiA8/3T9MPADCdD1bF8YBHZUsYAaYGfRFuGIb L60vUqGdRfHCqg4p4+vX9Aq0IAnUbRFwLL/rrmHso/bV63Lfur1PZZrxpxCLTKA6qGDj0j4UNNv5 1LaqSIQwCSZsQtb7hDxoA3GZ8b9tA+T5cILInW6S9YS5F3Z+4su8LBoty5As5VgMTi2JJ3mwFDDP m2WZTGiJCQC249lsY/ttlnFNwT94z3/8UCsxTf3KxQ75KnepAGDMYSt6f/m2yuFHxsvz5UtqEj39 5Lk9Fl3VwDhhFlgyQUBrYKGrJSET/P+I1FrNUlBr0XuzoYl5hxb5LuAQU5gNAiaf7gtkC2bwolv+ r2w3/Et9652A5zeWqzGPnDOPZzC2YCziRsfB6Ey7BDWx+NP2IKQLIysYRqyXOcYQf6kNG6M9rJFy Pua0jigjkUF74KKgZ30hmOz/dM3VExq3itLnYPrT6AzJA82/yWOX6YUbCPT2XwX9ueI1V/36R7Vm hS6Y8UDnECH2DpjmD0t9ZAE99ga3MPY0O4KvjFefKRJseDaKkvIlndECOXukSRfxVR6In5l7F5z+ eJdyKazZwNaSVkvL5dP3Ukiv1BLsRNvGVWN1aGgyu4YdCI7RpVoWzM58m7dIuceB1ckdMJuE93yZ AMZRQ4wHAbFZQOd+qgSZ03lMMc5sUl7nIYEc57a8PMow4p6+9tpMgPxyN0GJI8oP98m/LJ0/IxMI XDjJ9T5McrP6exRC9yuwugJuFHwCM= X-QQ-XMRINFO: NyFYKkN4Ny6FuXrnB5Ye7Aabb3ujjtK+gg== From: Yangyu Chen To: linux-riscv@lists.infradead.org Cc: linux-kernel@vger.kernel.org, Anup Patel , Samuel Holland , Charles Mirabile , Lucas Zampieri , Thomas Gleixner , Paul Walmsley , Palmer Dabbelt , Mason Huo , Zhang Xincheng , Charlie Jenkins , Marc Zyngier , Sia Jee Heng , Ley Foon Tan , Yangyu Chen Subject: [PATCH v2] irqchip/sifive-plic: Fix insufficient irq_groups allocation Date: Wed, 21 Jan 2026 13:45:26 +0800 X-OQ-MSGID: <20260121054526.3576962-1-cyy@cyyself.name> X-Mailer: git-send-email 2.51.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Since the first irq source is 1 instead of 0, when the number of irqs is multiple of 32, the last irq group will be ignored during allocation, saving, and restoring. This lead to memory corruption when accessing enable_save beyond allocated memory after commit 14ff9e54dd14 ("irqchip/sifive-plic: Cache the interrupt enable state") which will access enable_save for all sources during plic_probe. Thus, we should allocate irq_groups based on (nr_irqs + 1) instead of nr_irqs to avoid this issue. This is an long standing bug since Linux v6.4 but since the last irq source is rarely used, it may not be triggered in practice until commit 14ff9e54dd14 ("irqchip/sifive-plic: Cache the interrupt enable state"). Fixes: e80f0b6a2cf3 ("irqchip/irq-sifive-plic: Add syscore callbacks for hi= bernation") Fixes: 4d936f10ff80 ("irqchip/sifive-plic: Probe plic driver early for Allw= inner D1 platform") Fixes: 539d147ef69c ("irqchip/sifive-plic: Add support for UltraRISC DP1000= PLIC") Fixes: 14ff9e54dd14 ("irqchip/sifive-plic: Cache the interrupt enable state= ") Signed-off-by: Yangyu Chen --- Changes since v1: - Add more Fixes tags for earlier commits that are also affected by this bug. - Add more explanation about the bug's history. This can be reproduced by modifying the PLIC node in DT to have ndev as exactly multiple of 32, e.g., 32, 64, etc., then triggering some interrupts and checking dmesg for memory corruption: plic: plic@3c000000 { compatible =3D "riscv,plic0"; reg =3D <0x0 0x3c000000 0x0 0x4000000>; #interrupt-cells =3D <1>; interrupt-controller; interrupts-extended =3D <&cpu0_intc 11>, <&cpu0_intc 9>; riscv,max-priority =3D <7>; riscv,ndev =3D <64>; }; Here is an example dmesg log when ndev is 64: [ 0.077196] Unable to handle kernel paging request at virtual address ff= ffaf8000000000 [ 0.077205] Current swapper/0 pgtable: 4K pagesize, 48-bit VAs, pgdp=3D0= x0000000081c2d000 [ 0.077215] [ffffaf8000000000] pgd=3D000000009ffffc01, p4d=3D000000009ff= ffc01, pud=3D000000009ffff801, pmd=3D000000009ffff401, pte=3D00000000000000= 00 [ 0.077240] Oops [#1] [ 0.077246] Modules linked in: [ 0.077254] CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.19.0-rc6 = #36 NONE=20 [ 0.077266] Hardware name: XiangShan (DT) [ 0.077273] epc : __kmalloc_node_track_caller_noprof+0x1a0/0x524 [ 0.077284] ra : kstrdup+0x32/0x60 [ 0.077293] epc : ffffffff80253c70 ra : ffffffff801fa70e sp : ffff8f8000= 00b700 [ 0.077304] gp : ffffffff81a1b580 tp : ffffaf8080158000 t0 : 0000000000= 000264 [ 0.077313] t1 : 0000000000000003 t2 : 0000000000000000 s0 : ffff8f8000= 00b750 [ 0.077323] s1 : 0000000000000002 a0 : ffffaf8000000000 a1 : 0000000000= 000cc0 [ 0.077332] a2 : ffff8d800200bfc0 a3 : ffffffff81a5c5e0 a4 : ffffaf8000= 000000 [ 0.077342] a5 : 0000000000000003 a6 : ffffffffffffffff a7 : ffffaf8080= 001400 [ 0.077352] s2 : ffffaf80802ff178 s3 : ffffffff810107f0 s4 : 0000000000= 000000 [ 0.077362] s5 : 0000000000000000 s6 : ffff8f800000b9c0 s7 : ffffaf8080= 823200 [ 0.077372] s8 : ffffffff81a20580 s9 : ffffaf808012c990 s10: ffffffffff= ffffff [ 0.077382] s11: 0000000000000000 t3 : 0000000000000cc0 t4 : ffffffff80= 1fa764 [ 0.077391] t5 : 0000000000000000 t6 : 0000000000000263 [ 0.077399] status: 0000000200000120 badaddr: ffffaf8000000000 cause: 00= 0000000000000d [ 0.077409] [] __kmalloc_node_track_caller_noprof+0x1a= 0/0x524 [ 0.077422] [] kstrdup+0x32/0x60 [ 0.077433] [] kstrdup_const+0x28/0x34 [ 0.077444] [] __kernfs_new_node+0x3c/0x274 [ 0.077457] [] kernfs_new_node+0x44/0x6c [ 0.077470] [] kernfs_create_dir_ns+0x20/0x7c [ 0.077483] [] sysfs_create_dir_ns+0x60/0xcc [ 0.077497] [] kobject_add_internal+0xae/0x2d8 [ 0.077509] [] kobject_add+0x52/0xb8 [ 0.077520] [] __irq_alloc_descs+0x190/0x328 [ 0.077534] [] irq_domain_alloc_descs.part.0+0x46/0x78 [ 0.077549] [] irq_create_mapping_affinity+0x72/0xcc [ 0.077561] [] plic_probe+0x2e2/0x6c8 [ 0.077573] [] plic_platform_probe+0x10/0x18 [ 0.077586] [] platform_probe+0x46/0x80 [ 0.077600] [] really_probe+0x84/0x22c [ 0.077612] [] __driver_probe_device+0x5c/0xd4 [ 0.077625] [] driver_probe_device+0x2e/0xf4 [ 0.077639] [] __driver_attach+0x6e/0x14c [ 0.077652] [] bus_for_each_dev+0x60/0xb0 [ 0.077664] [] driver_attach+0x1a/0x24 [ 0.077676] [] bus_add_driver+0xca/0x1d8 [ 0.077689] [] driver_register+0x3e/0xdc [ 0.077702] [] __platform_driver_register+0x1c/0x24 [ 0.077716] [] plic_driver_init+0x1a/0x24 [ 0.077728] [] do_one_initcall+0x4e/0x1b8 [ 0.077740] [] kernel_init_freeable+0x25c/0x2dc [ 0.077754] [] kernel_init+0x1c/0x144 [ 0.077768] [] ret_from_fork_kernel+0xe/0xf4 [ 0.077781] [] ret_from_fork_kernel_asm+0x16/0x18 [ 0.077800] Code: 6308 0c63 2a06 0a63 2a05 e703 0308 8293 001f 972a (630= c) 7f73=20 [ 0.077809] ---[ end trace 0000000000000000 ]--- [ 0.077817] Kernel panic - not syncing: Attempted to kill init! exitcode= =3D0x0000000b [ 0.077827] ---[ end Kernel panic - not syncing: Attempted to kill init!= exitcode=3D0x0000000b ]--- --- drivers/irqchip/irq-sifive-plic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive= -plic.c index 210a57959637..d6515bf76444 100644 --- a/drivers/irqchip/irq-sifive-plic.c +++ b/drivers/irqchip/irq-sifive-plic.c @@ -293,7 +293,7 @@ static void plic_irq_resume(void *data) continue; =20 raw_spin_lock_irqsave(&handler->enable_lock, flags); - for (i =3D 0; i < DIV_ROUND_UP(priv->nr_irqs, 32); i++) { + for (i =3D 0; i < DIV_ROUND_UP(priv->nr_irqs + 1, 32); i++) { reg =3D handler->enable_base + i * sizeof(u32); writel(handler->enable_save[i], reg); } @@ -431,7 +431,7 @@ static u32 cp100_isolate_pending_irq(int nr_irq_groups,= struct plic_handler *han =20 static irq_hw_number_t cp100_get_hwirq(struct plic_handler *handler, void = __iomem *claim) { - int nr_irq_groups =3D DIV_ROUND_UP(handler->priv->nr_irqs, 32); + int nr_irq_groups =3D DIV_ROUND_UP(handler->priv->nr_irqs + 1, 32); u32 __iomem *enable =3D handler->enable_base; irq_hw_number_t hwirq =3D 0; u32 iso_mask; @@ -718,7 +718,7 @@ static int plic_probe(struct fwnode_handle *fwnode) context_id * CONTEXT_ENABLE_SIZE; handler->priv =3D priv; =20 - handler->enable_save =3D kcalloc(DIV_ROUND_UP(nr_irqs, 32), + handler->enable_save =3D kcalloc(DIV_ROUND_UP(nr_irqs + 1, 32), sizeof(*handler->enable_save), GFP_KERNEL); if (!handler->enable_save) { error =3D -ENOMEM; --=20 2.51.0