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

Rosen Penev <[email protected]> Mon, 3 Aug 2026 15:35:38 -0700
Newsgroups org.kernel.vger.linux-gpio,org.kernel.vger.linux-kernel,org.ozlabs.lists.linuxppc-dev
Message-ID <[email protected]>
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 <[email protected]>
---
 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