[tip: irq/drivers] irqchip/gic: Fix UBSAN shift-out-of-bounds in GIC helpers
From: tip-bot2 for Zhu Ling
Date: Thu Oct 15 2026 - 06:09:44 EST
The following commit has been merged into the irq/drivers branch of tip:
Commit-ID: 13ce14ca41a35f5ee90b77ffa57da91ce6048a2d
Gitweb: https://git.kernel.org/tip/13ce14ca41a35f5ee90b77ffa57da91ce6048a2d
Author: Zhu Ling <zhuling2709@xxxxxxxxxxxxxx>
AuthorDate: Tue, 29 Sep 2026 11:10:50 +08:00
Committer: Thomas Gleixner <tglx@xxxxxxxxxx>
CommitterDate: Thu, 15 Oct 2026 11:55:41 +02:00
irqchip/gic: Fix UBSAN shift-out-of-bounds in GIC helpers
When running with UBSAN enabled, enabling a GPIO controller that uses a
GIC interrupt as its parent triggers several shift-out-of-bounds warnings:
shift-out-of-bounds in drivers/irqchip/irq-gic-common.c:50:21
left shift of 2 by 30 places cannot be represented in type 'int'
Similar reports are emitted from gic_poke_irq() and gic_peek_irq() in
drivers/irqchip/irq-gic-v3.c. The corresponding GICv2 helpers use the
same signed-shift pattern. These masks are generated by shifting signed
integer constants, which invokes undefined behavior when bit 31 is
selected.
Use BIT() to generate the masks with an unsigned type and make their
intent explicit.
Fixes: f27ecacc54cc ("[ARM] Add support for ARM GIC")
Fixes: 5c0c1f08abf0 ("ARM: 6150/1: gic: implement set_type")
Fixes: 021f653791ad ("irqchip: gic-v3: Initial support for GICv3")
Signed-off-by: Zhu Ling <zhuling2709@xxxxxxxxxxxxxx>
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxx>
Reviewed-by: Zenghui Yu (Huawei) <zenghui.yu@xxxxxxxxx>
Reviewed-by: Radu Rendec <radu@xxxxxxxxxx>
Acked-by: Marc Zyngier <maz@xxxxxxxxxx>
Link: https://lore.kernel.org/r/2fJDwUUYdEf2_eaRa041L9xkT8RkSWFeo7euOnqMbbPhUatLlEaAvGfB6sOspDmXaxO87Eh7bQLV9UolyjbMtZBT1wB2UGypjPOo0Z-RC0Q=@proton.me
Link: https://patch.msgid.link/20260929031050.16988-1-zhuling2709@xxxxxxxxxxxxxx
---
drivers/irqchip/irq-gic-common.c | 2 +-
drivers/irqchip/irq-gic-v3.c | 4 ++--
drivers/irqchip/irq-gic.c | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
index c776f91..8bd1eaa 100644
--- a/drivers/irqchip/irq-gic-common.c
+++ b/drivers/irqchip/irq-gic-common.c
@@ -48,7 +48,7 @@ void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
int gic_configure_irq(unsigned int irq, unsigned int type,
void __iomem *base)
{
- u32 confmask = 0x2 << ((irq % 16) * 2);
+ u32 confmask = BIT(((irq % 16) * 2) + 1);
u32 confoff = (irq / 16) * 4;
u32 val, oldval;
int ret = 0;
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 32a8ea4..b9a99f9 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -457,7 +457,7 @@ static int gic_peek_irq(struct irq_data *d, u32 offset)
u32 index, mask;
offset = convert_offset_index(d, offset, &index);
- mask = 1 << (index % 32);
+ mask = BIT(index % 32);
if (gic_irq_in_rdist(d))
base = gic_data_rdist_sgi_base();
@@ -473,7 +473,7 @@ static void gic_poke_irq(struct irq_data *d, u32 offset)
u32 index, mask;
offset = convert_offset_index(d, offset, &index);
- mask = 1 << (index % 32);
+ mask = BIT(index % 32);
if (gic_irq_in_rdist(d))
base = gic_data_rdist_sgi_base();
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index b2926a3..a5ca04e 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -178,14 +178,14 @@ static inline bool cascading_gic_irq(struct irq_data *d)
*/
static void gic_poke_irq(struct irq_data *d, u32 offset)
{
- u32 mask = 1 << (irqd_to_hwirq(d) % 32);
+ u32 mask = BIT(irqd_to_hwirq(d) % 32);
writel_relaxed(mask, gic_dist_base(d) + offset + (irqd_to_hwirq(d) / 32) * 4);
}
static int gic_peek_irq(struct irq_data *d, u32 offset)
{
- u32 mask = 1 << (irqd_to_hwirq(d) % 32);
+ u32 mask = BIT(irqd_to_hwirq(d) % 32);
return !!(readl_relaxed(gic_dist_base(d) + offset + (irqd_to_hwirq(d) / 32) * 4) & mask);
}