[PATCH v2] irqchip/gic: Fix UBSAN shift-out-of-bounds in GIC helpers
From: Zhu Ling
Date: Sun Sep 20 2026 - 22:21:48 EST
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. 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.
Signed-off-by: Zhu Ling <zhuling2709@xxxxxxxxxxxxxx>
---
Changes in v2:
- Use BIT() instead of explicit unsigned shifts, as suggested by Marc.
- Drop the redundant introductory text from the email.
- Update the author email address.
Link: https://lore.kernel.org/r/2fJDwUUYdEf2_eaRa041L9xkT8RkSWFeo7euOnqMbbPhUatLlEaAvGfB6sOspDmXaxO87Eh7bQLV9UolyjbMtZBT1wB2UGypjPOo0Z-RC0Q=@proton.me
---
drivers/irqchip/irq-gic-common.c | 2 +-
drivers/irqchip/irq-gic-v3.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
index c776f9142610..8bd1eaa54295 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 6e1fa5b247fc..15110d47ddb0 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();
--
2.43.0