Thread (12 messages) flat view 12 messages, 3 authors, 17h ago

[PATCHv2 7/8] gpio: ppc44x: fix undefined behavior in GPIO_MASK2 macro

From: Rosen Penev <hidden>
Date: 2026-08-03 22:35:55
Also in: linux-gpio, lkml
Subsystem: gpio subsystem, the rest · Maintainers: Linus Walleij, Bartosz Golaszewski, Linus Torvalds

Shifting a 32-bit unsigned integer by 32 or more places is undefined
behavior in C. GPIO_MASK2 computes its shift amount as (gpio) * 2, and
for pins 16-31 in the OSRH/TSRH bank this yields shifts of 32-62.
While this happens to work on PowerPC because slw masks the shift count
to the low 5 bits, compilers performing value-range propagation may
assume the else branch is unreachable and optimize it away, or may
evaluate the shift as zero on other architectures via COMPILE_TEST.

Mask gpio to the 16-pin bank index so the shift stays within [0, 30].
The registers are banked (OSRL/TSRL for gpio 0-15, OSRH/TSRH for
gpio 16-31) with an identical 2-bit-per-pin layout from MSB to LSB,
so masking to the within-bank index preserves the intended behavior.

Assisted-by: opencode:big-pickle
Signed-off-by: Rosen Penev <redacted>
---
 drivers/gpio/gpio-ppc44x.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpio/gpio-ppc44x.c b/drivers/gpio/gpio-ppc44x.c
index fd543fbb959a..9fdc84e922f4 100644
--- a/drivers/gpio/gpio-ppc44x.c
+++ b/drivers/gpio/gpio-ppc44x.c
@@ -19,7 +19,7 @@
 #include <linux/platform_device.h>
 
 #define GPIO_MASK(gpio)		(0x80000000 >> (gpio))
-#define GPIO_MASK2(gpio)	(0xc0000000 >> ((gpio) * 2))
+#define GPIO_MASK2(gpio)	(0xc0000000 >> (((gpio) % 16) * 2))
 
 /* Physical GPIO register layout */
 struct ppc44x_gpio {
-- 
2.55.0

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help