Skip to contentSkip to conversation

treewide: Fix GENMASK misuses

PATCH Applied Joe Perches 30 participants 109 messages Jul 10, 2019 – Mar 9, 2020

Subsystems (30)
lore
Share & tools
lore

Joe Perches

author maintainer
#0 lore raw

cover treewide: Fix GENMASK misuses

These GENMASK uses are inverted argument order and the actual masks produced are incorrect. Fix them.

Add checkpatch tests to help avoid more misuses too.

Joe Perches (12):
checkpatch: Add GENMASK tests clocksource/drivers/npcm: Fix misuse of GENMASK macro
drm: aspeed_gfx: Fix misuse of GENMASK macro
iio: adc: max9611: Fix misuse of GENMASK macro irqchip/gic-v3-its: Fix misuse of GENMASK macro
mmc: meson-mx-sdio: Fix misuse of GENMASK macro
net: ethernet: mediatek: Fix misuses of GENMASK macro
net: stmmac: Fix misuses of GENMASK macro
rtw88: Fix misuse of GENMASK macro
phy: amlogic: G12A: Fix misuse of GENMASK macro
staging: media: cedrus: Fix misuse of GENMASK macro
ASoC: wcd9335: Fix misuse of GENMASK macro

 drivers/clocksource/timer-npcm7xx.c               |  2 +-
 drivers/gpu/drm/aspeed/aspeed_gfx.h               |  2 +-
 drivers/iio/adc/max9611.c                         |  2 +-
 drivers/irqchip/irq-gic-v3-its.c                  |  2 +-
 drivers/mmc/host/meson-mx-sdio.c                  |  2 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h       |  2 +-
 drivers/net/ethernet/mediatek/mtk_sgmii.c         |  2 +-
 drivers/net/ethernet/stmicro/stmmac/descs.h       |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c |  4 ++--
 drivers/net/wireless/realtek/rtw88/rtw8822b.c     |  2 +-
 drivers/phy/amlogic/phy-meson-g12a-usb2.c         |  2 +-
 drivers/staging/media/sunxi/cedrus/cedrus_regs.h  |  2 +-
 scripts/checkpatch.pl                             | 15 +++++++++++++++
 sound/soc/codecs/wcd-clsh-v2.c                    |  2 +-
 14 files changed, 29 insertions(+), 14 deletions(-)
Signature · 6 lines
2.15.0

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
author maintainer
#6 lore raw

PATCH 3/12 drm: aspeed_gfx: Fix misuse of GENMASK macro

Arguments are supposed to be ordered high then low.

---
 drivers/gpu/drm/aspeed/aspeed_gfx.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/aspeed/aspeed_gfx.h +1 -1
index a10358bb61ec..095ea03e5833 100644
@@ -74,7 +74,7 @@ int aspeed_gfx_create_output(struct drm_device *drm);
 /* CTRL2 */
 #define CRT_CTRL_DAC_EN			BIT(0)
 #define CRT_CTRL_VBLANK_LINE(x)		(((x) << 20) & CRT_CTRL_VBLANK_LINE_MASK)
-#define CRT_CTRL_VBLANK_LINE_MASK	GENMASK(20, 31)
+#define CRT_CTRL_VBLANK_LINE_MASK	GENMASK(31, 20)
 
 /* CRT_HORIZ0 */
 #define CRT_H_TOTAL(x)			(x)
Signature · 1 line
2.15.0
author maintainer
#21 lore raw

PATCH 6/12 mmc: meson-mx-sdio: Fix misuse of GENMASK macro

In reply to Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/mmc/host/meson-mx-sdio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mmc/host/meson-mx-sdio.c +1 -1
index 2d736e416775..ba9a63db73da 100644
@@ -73,7 +73,7 @@
 	#define MESON_MX_SDIO_IRQC_IF_CONFIG_MASK		GENMASK(7, 6)
 	#define MESON_MX_SDIO_IRQC_FORCE_DATA_CLK		BIT(8)
 	#define MESON_MX_SDIO_IRQC_FORCE_DATA_CMD		BIT(9)
-	#define MESON_MX_SDIO_IRQC_FORCE_DATA_DAT_MASK		GENMASK(10, 13)
+	#define MESON_MX_SDIO_IRQC_FORCE_DATA_DAT_MASK		GENMASK(13, 10)
 	#define MESON_MX_SDIO_IRQC_SOFT_RESET			BIT(15)
 	#define MESON_MX_SDIO_IRQC_FORCE_HALT			BIT(30)
 	#define MESON_MX_SDIO_IRQC_HALT_HOLE			BIT(31)
Signature · 1 line
2.15.0
author maintainer
#24 lore raw

PATCH 7/12 net: ethernet: mediatek: Fix misuses of GENMASK macro

In reply to Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +-
 drivers/net/ethernet/mediatek/mtk_sgmii.c   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.h +1 -1
index 876ce6798709..221012ecb845 100644
@@ -712,7 +712,7 @@ struct mtk_soc_data {
 #define MTK_MAX_DEVS			2
 
 #define MTK_SGMII_PHYSPEED_AN          BIT(31)
-#define MTK_SGMII_PHYSPEED_MASK        GENMASK(0, 2)
+#define MTK_SGMII_PHYSPEED_MASK        GENMASK(2, 0)
 #define MTK_SGMII_PHYSPEED_1000        BIT(0)
 #define MTK_SGMII_PHYSPEED_2500        BIT(1)
 #define MTK_HAS_FLAGS(flags, _x)       (((flags) & (_x)) == (_x))
drivers/net/ethernet/mediatek/mtk_sgmii.c +1 -1
index 136f90ce5a65..ff509d42d818 100644
@@ -82,7 +82,7 @@ int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id)
 		return -EINVAL;
 
 	regmap_read(ss->regmap[id], ss->ana_rgc3, &val);
-	val &= ~GENMASK(2, 3);
+	val &= ~GENMASK(3, 2);
 	mode = ss->flags[id] & MTK_SGMII_PHYSPEED_MASK;
 	val |= (mode == MTK_SGMII_PHYSPEED_1000) ? 0 : BIT(2);
 	regmap_write(ss->regmap[id], ss->ana_rgc3, val);
Signature · 1 line
2.15.0
author maintainer
#41 lore raw

PATCH 12/12 ASoC: wcd9335: Fix misuse of GENMASK macro

In reply to Joe Perches

Arguments are supposed to be ordered high then low.

---
 sound/soc/codecs/wcd-clsh-v2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/codecs/wcd-clsh-v2.c +1 -1
index c397d713f01a..cc5a9c9b918b 100644
@@ -65,7 +65,7 @@ struct wcd_clsh_ctrl {
 #define WCD9XXX_FLYBACK_EN_PWDN_WITH_DELAY			0
 #define WCD9XXX_RX_BIAS_FLYB_BUFF			WCD9335_REG(0x6, 0xC7)
 #define WCD9XXX_RX_BIAS_FLYB_VNEG_5_UA_MASK		GENMASK(7, 4)
-#define WCD9XXX_RX_BIAS_FLYB_VPOS_5_UA_MASK		GENMASK(0, 3)
+#define WCD9XXX_RX_BIAS_FLYB_VPOS_5_UA_MASK		GENMASK(3, 0)
 #define WCD9XXX_HPH_L_EN				WCD9335_REG(0x6, 0xD3)
 #define WCD9XXX_HPH_CONST_SEL_L_MASK			GENMASK(7, 3)
 #define WCD9XXX_HPH_CONST_SEL_BYPASS			0
Signature · 1 line
2.15.0
author maintainer
#1 lore raw

PATCH 1/12 checkpatch: Add GENMASK tests

In reply to Joe Perches

This macro is easy to misuse as it's odd argument order.

If specified with simple decimal values, make sure the arguments are ordered high then low.

Also check if any argument is > 32 where instead of GENMASK, GENMASK_ULL should be used.

---
 scripts/checkpatch.pl | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
scripts/checkpatch.pl +15 -0
index 6cb99ec62000..d37bbe33524b 100755
@@ -6368,6 +6368,21 @@ sub process {
 			     "switch default: should use break\n" . $herectx);
 		}
 
+# check for misuses of GENMASK
+		if ($line =~ /\b(GENMASK(?:_ULL)?)\s*\(\s*(\d+)\s*,\s*(\d+)\s*\)/) {
+			my $type = $1;
+			my $high = $2;
+			my $low = $3;
+			if ($high < $low) {
+				ERROR("GENMASK",
+				      "$type argument order is high then low\n" . $herecurr);
+			}
+			if ($type eq "GENMASK" && ($high >= 32 || $low >= 32)) {
+				ERROR("GENMASK",
+				      "$type with arguments >= 32 should use GENMASK_ULL\n" . $herecurr);
+			}
+		}
+
 # check for gcc specific __FUNCTION__
 		if ($line =~ /\b__FUNCTION__\b/) {
 			if (WARN("USE_FUNC",
Signature · 1 line
2.15.0
author maintainer
#3 lore raw

PATCH 2/12 clocksource/drivers/npcm: Fix misuse of GENMASK macro

In reply to Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/clocksource/timer-npcm7xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clocksource/timer-npcm7xx.c +1 -1
index 7a9bb5532d99..8a30da7f083b 100644
@@ -32,7 +32,7 @@
 #define NPCM7XX_Tx_INTEN		BIT(29)
 #define NPCM7XX_Tx_COUNTEN		BIT(30)
 #define NPCM7XX_Tx_ONESHOT		0x0
-#define NPCM7XX_Tx_OPER			GENMASK(3, 27)
+#define NPCM7XX_Tx_OPER			GENMASK(27, 3)
 #define NPCM7XX_Tx_MIN_PRESCALE		0x1
 #define NPCM7XX_Tx_TDR_MASK_BITS	24
 #define NPCM7XX_Tx_MAX_CNT		0xFFFFFF
Signature · 1 line
2.15.0
author maintainer
#25 lore raw

PATCH 8/12 net: stmmac: Fix misuses of GENMASK macro

In reply to Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/net/ethernet/stmicro/stmmac/descs.h       | 2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/net/ethernet/stmicro/stmmac/descs.h +1 -1
index 10429b05f932..9f0b9a9e63b3 100644
@@ -123,7 +123,7 @@
 #define	ETDES1_BUFFER2_SIZE_SHIFT	16
 
 /* Extended Receive descriptor definitions */
-#define	ERDES4_IP_PAYLOAD_TYPE_MASK	GENMASK(2, 6)
+#define	ERDES4_IP_PAYLOAD_TYPE_MASK	GENMASK(6, 2)
 #define	ERDES4_IP_HDR_ERR		BIT(3)
 #define	ERDES4_IP_PAYLOAD_ERR		BIT(4)
 #define	ERDES4_IP_CSUM_BYPASSED		BIT(5)
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +2 -2
index 6d5cba4075eb..4c5db00c1d18 100644
@@ -192,7 +192,7 @@ static const struct emac_variant emac_variant_h6 = {
 
 /* Used in RX_CTL1*/
 #define EMAC_RX_MD              BIT(1)
-#define EMAC_RX_TH_MASK		GENMASK(4, 5)
+#define EMAC_RX_TH_MASK		GENMASK(5, 4)
 #define EMAC_RX_TH_32		0
 #define EMAC_RX_TH_64		(0x1 << 4)
 #define EMAC_RX_TH_96		(0x2 << 4)
@@ -203,7 +203,7 @@ static const struct emac_variant emac_variant_h6 = {
 /* Used in TX_CTL1*/
 #define EMAC_TX_MD              BIT(1)
 #define EMAC_TX_NEXT_FRM        BIT(2)
-#define EMAC_TX_TH_MASK		GENMASK(8, 10)
+#define EMAC_TX_TH_MASK		GENMASK(10, 8)
 #define EMAC_TX_TH_64		0
 #define EMAC_TX_TH_128		(0x1 << 8)
 #define EMAC_TX_TH_192		(0x2 << 8)
Signature · 1 line
2.15.0
author maintainer
#30 lore raw

PATCH 10/12 phy: amlogic: G12A: Fix misuse of GENMASK macro

In reply to Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/phy/amlogic/phy-meson-g12a-usb2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/phy/amlogic/phy-meson-g12a-usb2.c +1 -1
index 9065ffc85eb4..cd7eccab2649 100644
@@ -66,7 +66,7 @@
 #define PHY_CTRL_R14						0x38
 	#define PHY_CTRL_R14_I_RDP_EN				BIT(0)
 	#define PHY_CTRL_R14_I_RPU_SW1_EN			BIT(1)
-	#define PHY_CTRL_R14_I_RPU_SW2_EN			GENMASK(2, 3)
+	#define PHY_CTRL_R14_I_RPU_SW2_EN			GENMASK(3, 2)
 	#define PHY_CTRL_R14_PG_RSTN				BIT(4)
 	#define PHY_CTRL_R14_I_C2L_DATA_16_8			BIT(5)
 	#define PHY_CTRL_R14_I_C2L_ASSERT_SINGLE_EN_ZERO	BIT(6)
Signature · 1 line
2.15.0
author maintainer
#27 lore raw

PATCH 9/12 rtw88: Fix misuse of GENMASK macro

In reply to Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/net/wireless/realtek/rtw88/rtw8822b.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/realtek/rtw88/rtw8822b.c +1 -1
index 1172f6c0605b..d61d534396c7 100644
@@ -997,7 +997,7 @@ static void rtw8822b_do_iqk(struct rtw_dev *rtwdev)
 	rtw_write_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK, 0x0);
 
 	reload = !!rtw_read32_mask(rtwdev, REG_IQKFAILMSK, BIT(16));
-	iqk_fail_mask = rtw_read32_mask(rtwdev, REG_IQKFAILMSK, GENMASK(0, 7));
+	iqk_fail_mask = rtw_read32_mask(rtwdev, REG_IQKFAILMSK, GENMASK(7, 0));
 	rtw_dbg(rtwdev, RTW_DBG_PHY,
 		"iqk counter=%d reload=%d do_iqk_cnt=%d n_iqk_fail(mask)=0x%02x\n",
 		counter, reload, ++do_iqk_cnt, iqk_fail_mask);
Signature · 1 line
2.15.0
author maintainer
#34 lore raw

PATCH 11/12 staging: media: cedrus: Fix misuse of GENMASK macro

In reply to Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/media/sunxi/cedrus/cedrus_regs.h +1 -1
index 3e9931416e45..ddd29788d685 100644
@@ -110,7 +110,7 @@
 #define VE_DEC_MPEG_MBADDR			(VE_ENGINE_DEC_MPEG + 0x10)
 
 #define VE_DEC_MPEG_MBADDR_X(w)			(((w) << 8) & GENMASK(15, 8))
-#define VE_DEC_MPEG_MBADDR_Y(h)			(((h) << 0) & GENMASK(0, 7))
+#define VE_DEC_MPEG_MBADDR_Y(h)			(((h) << 0) & GENMASK(7, 0))
 
 #define VE_DEC_MPEG_CTRL			(VE_ENGINE_DEC_MPEG + 0x14)
 
Signature · 1 line
2.15.0
author maintainer
#12 lore raw

PATCH 4/12 iio: adc: max9611: Fix misuse of GENMASK macro

In reply to Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/iio/adc/max9611.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/max9611.c +1 -1
index 917223d5ff5b..0e3c6529fc4c 100644
@@ -83,7 +83,7 @@
 #define MAX9611_TEMP_MAX_POS		0x7f80
 #define MAX9611_TEMP_MAX_NEG		0xff80
 #define MAX9611_TEMP_MIN_NEG		0xd980
-#define MAX9611_TEMP_MASK		GENMASK(7, 15)
+#define MAX9611_TEMP_MASK		GENMASK(15, 7)
 #define MAX9611_TEMP_SHIFT		0x07
 #define MAX9611_TEMP_RAW(_r)		((_r) >> MAX9611_TEMP_SHIFT)
 #define MAX9611_TEMP_SCALE_NUM		1000000
Signature · 1 line
2.15.0
author maintainer
#18 lore raw

PATCH 5/12 irqchip/gic-v3-its: Fix misuse of GENMASK macro

In reply to Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/irqchip/irq-gic-v3-its.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/irqchip/irq-gic-v3-its.c +1 -1
index 35500801dc2b..730fbe0e2a9d 100644
@@ -185,7 +185,7 @@ static struct its_collection *dev_event_to_col(struct its_device *its_dev,
 
 static struct its_collection *valid_col(struct its_collection *col)
 {
-	if (WARN_ON_ONCE(col->target_address & GENMASK_ULL(0, 15)))
+	if (WARN_ON_ONCE(col->target_address & GENMASK_ULL(15, 0)))
 		return NULL;
 
 	return col;
Signature · 1 line
2.15.0
Acked-by on v1 9/12
#28 lore raw

RE: [PATCH 09/12] rtw88: Fix misuse of GENMASK macro

In reply to Joe Perches
Quoted 23 lines

Subject: [PATCH 09/12] rtw88: Fix misuse of GENMASK macro

Arguments are supposed to be ordered high then low.

---
 drivers/net/wireless/realtek/rtw88/rtw8822b.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/realtek/rtw88/rtw8822b.c +1 -1
index 1172f6c0605b..d61d534396c7 100644
@@ -997,7 +997,7 @@ static void rtw8822b_do_iqk(struct rtw_dev *rtwdev)
 	rtw_write_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK, 0x0);
 
 	reload = !!rtw_read32_mask(rtwdev, REG_IQKFAILMSK, BIT(16));
-	iqk_fail_mask = rtw_read32_mask(rtwdev, REG_IQKFAILMSK,
 GENMASK(0, 7));
+	iqk_fail_mask = rtw_read32_mask(rtwdev, REG_IQKFAILMSK,
 GENMASK(7, 0));
 	rtw_dbg(rtwdev, RTW_DBG_PHY,
Quoted 4 lines

"iqk counter=%d reload=%d do_iqk_cnt=%d
n_iqk_fail(mask)=0x%02x\n",
counter, reload, ++do_iqk_cnt, iqk_fail_mask);
--

That's correct. Thanks.

Yan-Hsuan

Acked-by on v1 11/12
#35 lore raw

Re: [PATCH 11/12] staging: media: cedrus: Fix misuse of GENMASK macro

In reply to Joe Perches

Hi,

Quoted 3 lines · Joe Perches

Arguments are supposed to be ordered high then low.

Good catch, thanks!

Cheers,

Paul

Quoted 20 lines
---
 drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/media/sunxi/cedrus/cedrus_regs.h +1 -1
index 3e9931416e45..ddd29788d685 100644
@@ -110,7 +110,7 @@
 #define VE_DEC_MPEG_MBADDR			(VE_ENGINE_DEC_MPEG + 0x10)
 
 #define VE_DEC_MPEG_MBADDR_X(w)			(((w) << 8) & GENMASK(15, 8))
-#define VE_DEC_MPEG_MBADDR_Y(h)			(((h) << 0) & GENMASK(0, 7))
+#define VE_DEC_MPEG_MBADDR_Y(h)			(((h) << 0) & GENMASK(7, 0))
 
 #define VE_DEC_MPEG_CTRL			(VE_ENGINE_DEC_MPEG + 0x14)
 
Signature · 1 line
2.15.0
Signature · 3 lines
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
Acked-by on v1 5/12
#19 lore raw

Re: [PATCH 05/12] irqchip/gic-v3-its: Fix misuse of GENMASK macro

In reply to Joe Perches
Quoted 13 lines · Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/irqchip/irq-gic-v3-its.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/irqchip/irq-gic-v3-its.c +0 -0
index 35500801dc2b..730fbe0e2a9d 100644

drivers/irqchip/irq-gic-v3-its.c static struct its_collection *dev_event_to_col(struct its_device *its_dev, · line 191

Quoted 8 lines
drivers/irqchip/irq-gic-v3-its.c +1 -1
@@ -185,7 +185,7 @@ static struct its_collection *dev_event_to_col(struct its_device *its_dev,
 
 static struct its_collection *valid_col(struct its_collection *col)
 {
-	if (WARN_ON_ONCE(col->target_address & GENMASK_ULL(0, 15)))
+	if (WARN_ON_ONCE(col->target_address & GENMASK_ULL(15, 0)))
 		return NULL;
 
 	return col;

Well caught.

Thanks,

	M.
Signature · 1 line
Jazz is not dead. It just smells funny...
#20 lore raw

[tip:irq/urgent] irqchip/gic-v3-its: Fix misuse of GENMASK macro

In reply to Joe Perches
irqchip/gic-v3-its: Fix misuse of GENMASK macro
Commit-ID:  20faba848752901de23a4d45a1174d64d2069dde
Gitweb:     https://git.kernel.org/tip/20faba848752901de23a4d45a1174d64d2069dde
Author:     Joe Perches <[email protected]>
AuthorDate: Tue, 9 Jul 2019 22:04:18 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Wed, 10 Jul 2019 11:04:17 +0200

irqchip/gic-v3-its: Fix misuse of GENMASK macro

Arguments are supposed to be ordered high then low.

---
 drivers/irqchip/irq-gic-v3-its.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/irqchip/irq-gic-v3-its.c +1 -1
index 35500801dc2b..730fbe0e2a9d 100644
@@ -185,7 +185,7 @@ static struct its_collection *dev_event_to_col(struct its_device *its_dev,
 
 static struct its_collection *valid_col(struct its_collection *col)
 {
-	if (WARN_ON_ONCE(col->target_address & GENMASK_ULL(0, 15)))
+	if (WARN_ON_ONCE(col->target_address & GENMASK_ULL(15, 0)))
 		return NULL;
 
 	return col;
#4 lore raw

[tip:timers/urgent] clocksource/drivers/npcm: Fix misuse of GENMASK macro

In reply to Joe Perches
clocksource/drivers/npcm: Fix misuse of GENMASK macro
Commit-ID:  9bdd7bb3a8447fe841cd37ddd9e0a6974b06a0bb
Gitweb:     https://git.kernel.org/tip/9bdd7bb3a8447fe841cd37ddd9e0a6974b06a0bb
Author:     Joe Perches <[email protected]>
AuthorDate: Tue, 9 Jul 2019 22:04:15 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Wed, 10 Jul 2019 11:05:26 +0200

clocksource/drivers/npcm: Fix misuse of GENMASK macro

Arguments are supposed to be ordered high then low.

---
 drivers/clocksource/timer-npcm7xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clocksource/timer-npcm7xx.c +1 -1
index 7a9bb5532d99..8a30da7f083b 100644
@@ -32,7 +32,7 @@
 #define NPCM7XX_Tx_INTEN		BIT(29)
 #define NPCM7XX_Tx_COUNTEN		BIT(30)
 #define NPCM7XX_Tx_ONESHOT		0x0
-#define NPCM7XX_Tx_OPER			GENMASK(3, 27)
+#define NPCM7XX_Tx_OPER			GENMASK(27, 3)
 #define NPCM7XX_Tx_MIN_PRESCALE		0x1
 #define NPCM7XX_Tx_TDR_MASK_BITS	24
 #define NPCM7XX_Tx_MAX_CNT		0xFFFFFF
#43 lore raw
In reply to Joe Perches
Quoted 7 lines · Joe Perches

These GENMASK uses are inverted argument order and the actual masks produced are incorrect. Fix them.

Add checkpatch tests to help avoid more misuses too.

Joe Perches (12):
checkpatch: Add GENMASK tests

IMHO this doesn't make a lot of sense as a checkpatch test - just throw in a BUILD_BUG_ON()?

johannes

#44 lore raw
Quoted 11 lines · Johannes Berg
Quoted 7 lines · Joe Perches

These GENMASK uses are inverted argument order and the actual masks produced are incorrect. Fix them.

Add checkpatch tests to help avoid more misuses too.

Joe Perches (12):
checkpatch: Add GENMASK tests

IMHO this doesn't make a lot of sense as a checkpatch test - just throw in a BUILD_BUG_ON()?

My personal take on this is that GENMASK() is really not useful, it's just pure obfuscation and leads to exactly these kinds of mistakes.

Yes, I fully understand the argument that you can just specify the start and end bits, and it _in theory_ makes the code more readable.

However, the problem is when writing code. GENMASK(a, b). Is a the starting bit or ending bit? Is b the number of bits? It's confusing and causes mistakes resulting in incorrect code. A BUILD_BUG_ON() can catch some of the cases, but not all of them.

For example:

	GENMASK(6, 2)

would satisify the requirement that a > b, so a BUILD_BUG_ON() will not trigger, but was the author meaning 0x3c or 0xc0?

Personally, I've decided I am _not_ going to use GENMASK() in my code because I struggle to get the macro arguments correct - I'm _much_ happier, and it is way more reliable for me to write the mask in hex notation.

I think this is where use of a ternary operator would come in use. The normal way of writing a number of bits tends to be "a:b", so if GENMASK took something like GENMASK(6:2), then I'd have less issue with it, because it's argument is then in a familiar notation.

Yes, I'm sure that someone will point out that the GENMASK arguments are just in the same order, but that doesn't prevent _me_ frequently getting it wrong - and that's the point. The macro seems to me to cause more problems than it solves.

Signature · 7 lines
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
#26 lore raw

RE: [PATCH 08/12] net: stmmac: Fix misuses of GENMASK macro

In reply to Joe Perches

From: Joe Perches <[email protected]>
Date: Jul/10/2019, 06:04:21 (UTC+00:00)

Quoted 3 lines

Arguments are supposed to be ordered high then low.

If you submit another version please add:

Fixes 293e4365a1ad ("stmmac: change descriptor layout")
Fixes 9f93ac8d4085 ("net-next: stmmac: Add dwmac-sun8i")

---
Thanks,
Jose Miguel Abreu

author maintainer
#45 lore raw
In reply to Russell King - ARM Linux admin
Quoted 5 lines · Russell King - ARM Linux admin
Quoted 4 lines · Johannes Berg
Quoted 3 lines · Joe Perches

These GENMASK uses are inverted argument order and the actual masks produced are incorrect. Fix them.

Quoted 7 lines
Quoted 7 lines
Quoted 4 lines

Add checkpatch tests to help avoid more misuses too.

Joe Perches (12):
checkpatch: Add GENMASK tests

IMHO this doesn't make a lot of sense as a checkpatch test - just throw in a BUILD_BUG_ON()?

I tried that.

It'd can't be done as it's used in declarations and included in asm files and it uses the UL() macro.

I also tried just making it do the right thing whatever the argument order.

Oh well.

Quoted 10 lines

My personal take on this is that GENMASK() is really not useful, it's just pure obfuscation and leads to exactly these kinds of mistakes.

Yes, I fully understand the argument that you can just specify the start and end bits, and it _in theory_ makes the code more readable.

However, the problem is when writing code. GENMASK(a, b). Is a the starting bit or ending bit? Is b the number of bits? It's confusing and causes mistakes resulting in incorrect code. A BUILD_BUG_ON() can catch some of the cases, but not all of them.

It's a horrid little macro and I agree with Russell.

I also think if it existed at all it should have been GENMASK(low, high) not GENMASK(high, low).

I

author maintainer
#46 lore raw
Quoted 14 lines · Joe Perches
Quoted 5 lines · Russell King - ARM Linux admin
Quoted 4 lines · Johannes Berg
Quoted 3 lines · Joe Perches

These GENMASK uses are inverted argument order and the actual masks produced are incorrect. Fix them.

Quoted 7 lines
Quoted 7 lines
Quoted 4 lines

Add checkpatch tests to help avoid more misuses too.

Joe Perches (12):
checkpatch: Add GENMASK tests

IMHO this doesn't make a lot of sense as a checkpatch test - just throw in a BUILD_BUG_ON()?

Quoted 8 lines

I tried that.

It'd can't be done as it's used in declarations
and included in asm files and it uses the UL()
macro.

I also tried just making it do the right thing
whatever the argument order.

I forgot.

I also made all those arguments when it was
introduced in 2013.

https://lore.kernel.org/patchwork/patch/414248/

Quoted 1 line

Oh well.

yeah.

maintainer
#107 lore raw
In reply to Joe Perches

From: Joe Perches <[email protected]>
Date: Tue, 9 Jul 2019 22:04:13 -0700

Quoted 4 lines

These GENMASK uses are inverted argument order and the actual masks produced are incorrect. Fix them.

Add checkpatch tests to help avoid more misuses too.

Patches #7 and #8 applied to 'net', with appropriate Fixes tags added to #8.

#108 lore raw
In reply to Joe Perches

Hi Joe,

Quoted 19 lines · Joe Perches

These GENMASK uses are inverted argument order and the actual masks produced are incorrect. Fix them.

Add checkpatch tests to help avoid more misuses too.

Joe Perches (12):
checkpatch: Add GENMASK tests clocksource/drivers/npcm: Fix misuse of GENMASK macro
drm: aspeed_gfx: Fix misuse of GENMASK macro
iio: adc: max9611: Fix misuse of GENMASK macro irqchip/gic-v3-its: Fix misuse of GENMASK macro
mmc: meson-mx-sdio: Fix misuse of GENMASK macro
net: ethernet: mediatek: Fix misuses of GENMASK macro
net: stmmac: Fix misuses of GENMASK macro
rtw88: Fix misuse of GENMASK macro
phy: amlogic: G12A: Fix misuse of GENMASK macro
staging: media: cedrus: Fix misuse of GENMASK macro
ASoC: wcd9335: Fix misuse of GENMASK macro

Quoted 16 lines
 drivers/clocksource/timer-npcm7xx.c               |  2 +-
 drivers/gpu/drm/aspeed/aspeed_gfx.h               |  2 +-
 drivers/iio/adc/max9611.c                         |  2 +-
 drivers/irqchip/irq-gic-v3-its.c                  |  2 +-
 drivers/mmc/host/meson-mx-sdio.c                  |  2 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h       |  2 +-
 drivers/net/ethernet/mediatek/mtk_sgmii.c         |  2 +-
 drivers/net/ethernet/stmicro/stmmac/descs.h       |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c |  4 ++--
 drivers/net/wireless/realtek/rtw88/rtw8822b.c     |  2 +-
 drivers/phy/amlogic/phy-meson-g12a-usb2.c         |  2 +-
 drivers/staging/media/sunxi/cedrus/cedrus_regs.h  |  2 +-
 scripts/checkpatch.pl                             | 15 +++++++++++++++
 sound/soc/codecs/wcd-clsh-v2.c                    |  2 +-
 14 files changed, 29 insertions(+), 14 deletions(-)

After adding following compile time check:

------

Makefile +0 -0
index 5102b2bbd224..ac4ea5f443a9 100644
@@ -457,7 +457,7 @@ KBUILD_AFLAGS   := -D__ASSEMBLY__ -fno-PIE

 KBUILD_CFLAGS   := -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs \
                   -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE \
                   -Werror=implicit-function-declaration -Werror=implicit-int \
-                  -Wno-format-security \
+                  -Wno-format-security -Werror=div-by-zero \
                   -std=gnu89
 KBUILD_CPPFLAGS := -D__KERNEL__
 KBUILD_AFLAGS_KERNEL :=

include/linux/bits.h +0 -0
index 669d69441a62..61d74b103055 100644
@@ -19,11 +19,11 @@

  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. */
 #define GENMASK(h, l) \
-       (((~UL(0)) - (UL(1) << (l)) + 1) & \
+       (((~UL(0)) - (UL(1) << (l)) + 1 + 0/((h) >= (l))) & \
         (~UL(0) >> (BITS_PER_LONG - 1 - (h))))

 #define GENMASK_ULL(h, l) \
-       (((~ULL(0)) - (ULL(1) << (l)) + 1) & \
+       (((~ULL(0)) - (ULL(1) << (l)) + 1 + 0/((h) >= (l))) & \
         (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))

 #endif /* __LINUX_BITS_H */

-------

I was able to detect one more GENMASK misue (AARCH64, allyesconfig):

  CC      drivers/phy/rockchip/phy-rockchip-inno-hdmi.o
In file included from ../include/linux/bitops.h:5:0,
                 from ../include/linux/kernel.h:12,
                 from ../include/linux/clk.h:13,
                 from ../drivers/phy/rockchip/phy-rockchip-inno-hdmi.c:9:
../drivers/phy/rockchip/phy-rockchip-inno-hdmi.c: In function ‘inno_hdmi_phy_rk3328_power_on’:
../include/linux/bits.h:22:37: error: division by zero [-Werror=div-by-zero] (((~UL(0)) - (UL(1) << (l)) + 1 + 0/((h) >= (l))) & \
                                     ^ ../drivers/phy/rockchip/phy-rockchip-inno-hdmi.c:24:42: note: in expansion of macro ‘GENMASK’
 #define UPDATE(x, h, l)  (((x) << (l)) & GENMASK((h), (l))) ^~~~~~~ ../drivers/phy/rockchip/phy-rockchip-inno-hdmi.c:201:50: note: in expansion of macro ‘UPDATE’
 #define RK3328_TERM_RESISTOR_CALIB_SPEED_7_0(x)  UPDATE(x, 7, 9) ^~~~~~ ../drivers/phy/rockchip/phy-rockchip-inno-hdmi.c:1046:26: note: in expansion of macro ‘RK3328_TERM_RESISTOR_CALIB_SPEED_7_0’ inno_write(inno, 0xc6, RK3328_TERM_RESISTOR_CALIB_SPEED_7_0(v));

Of course I do not advise to add the check as is to Kernel - it is undefined behavior area AFAIK.

Regards

Andrzej

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

maintainer Applied
#13 lore raw

Re: [PATCH 04/12] iio: adc: max9611: Fix misuse of GENMASK macro

In reply to Joe Perches
Quoted 3 lines · On Tue, 9 Jul 2019 22:04:17 -0700 Joe Perches <[email protected]> wrote:

Arguments are supposed to be ordered high then low.

Applied to the fixes-togreg branch of iio.git and marked for stable etc.

Thanks,

Jonathan

Quoted 17 lines
---
 drivers/iio/adc/max9611.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/max9611.c +1 -1
index 917223d5ff5b..0e3c6529fc4c 100644
@@ -83,7 +83,7 @@
 #define MAX9611_TEMP_MAX_POS		0x7f80
 #define MAX9611_TEMP_MAX_NEG		0xff80
 #define MAX9611_TEMP_MIN_NEG		0xd980
-#define MAX9611_TEMP_MASK		GENMASK(7, 15)
+#define MAX9611_TEMP_MASK		GENMASK(15, 7)
 #define MAX9611_TEMP_SHIFT		0x07
 #define MAX9611_TEMP_RAW(_r)		((_r) >> MAX9611_TEMP_SHIFT)
 #define MAX9611_TEMP_SCALE_NUM		1000000
author maintainer
#14 lore raw

Re: [PATCH 04/12] iio: adc: max9611: Fix misuse of GENMASK macro

Quoted 9 lines · Jonathan Cameron
Quoted 3 lines · On Tue, 9 Jul 2019 22:04:17 -0700 Joe Perches <[email protected]> wrote:

Arguments are supposed to be ordered high then low.

Applied to the fixes-togreg branch of iio.git and marked for stable etc.

This mask is used in an init function called from a probe.

I don't have this hardware but it looks as if it could never have worked so I doubt the driver and the hardware have ever been tested.

Does anyone have this device in actual use?

	regval = ret & MAX9611_TEMP_MASK;

	if ((regval > MAX9611_TEMP_MAX_POS &&
	     regval < MAX9611_TEMP_MIN_NEG) ||
	     regval > MAX9611_TEMP_MAX_NEG) {
		dev_err(max9611->dev,
			"Invalid value received from ADC 0x%4x: aborting\n",
			regval);
		return -EIO;
	}
Quoted 21 lines

Thanks,

Jonathan

Quoted 17 lines
---
 drivers/iio/adc/max9611.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/max9611.c +1 -1
index 917223d5ff5b..0e3c6529fc4c 100644
@@ -83,7 +83,7 @@
 #define MAX9611_TEMP_MAX_POS		0x7f80
 #define MAX9611_TEMP_MAX_NEG		0xff80
 #define MAX9611_TEMP_MIN_NEG		0xd980
-#define MAX9611_TEMP_MASK		GENMASK(7, 15)
+#define MAX9611_TEMP_MASK		GENMASK(15, 7)
 #define MAX9611_TEMP_SHIFT		0x07
 #define MAX9611_TEMP_RAW(_r)		((_r) >> MAX9611_TEMP_SHIFT)
 #define MAX9611_TEMP_SCALE_NUM		1000000
#15 lore raw

Re: [PATCH 04/12] iio: adc: max9611: Fix misuse of GENMASK macro

Hi Joe, Jonathan,

Quoted 8 lines · Joe Perches
Quoted 7 lines · Jonathan Cameron
Quoted 3 lines · On Tue, 9 Jul 2019 22:04:17 -0700 Joe Perches <[email protected]> wrote:

Arguments are supposed to be ordered high then low.

Quoted 9 lines
Quoted 2 lines

Applied to the fixes-togreg branch of iio.git and marked for stable etc.

This mask is used in an init function called from a probe.

I don't have this hardware but it looks as if it could never have worked so I doubt the driver and the hardware have ever been tested.

Ups, this is embarassing! Thanks for noticing

I actually tested the device before sending the driver of course

Quoted 2 lines

Does anyone have this device in actual use?

The driver is currently in use in Renesas Gen3 Salvator boards:
arch/arm64/boot/dts/renesas/salvator-common.dtsi:466

I might need some time before I can actually test and tell what's happening though. It might work by pure chance. Fortunately the mask is only used for validation of the temperature reading at probe time, and I can tell this passes (we would have noticed otherwise, Salvator is one of the reference Gen3 platforms for upstream development).

As said I might need some time before I can test this, but the change is indeed correct.

Thanks
j

Quoted 35 lines
	regval = ret & MAX9611_TEMP_MASK;

	if ((regval > MAX9611_TEMP_MAX_POS &&
	     regval < MAX9611_TEMP_MIN_NEG) ||
	     regval > MAX9611_TEMP_MAX_NEG) {
		dev_err(max9611->dev,
			"Invalid value received from ADC 0x%4x: aborting\n",
			regval);
		return -EIO;
	}
Quoted 21 lines

Thanks,

Jonathan

Quoted 17 lines
---
 drivers/iio/adc/max9611.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/max9611.c +1 -1
index 917223d5ff5b..0e3c6529fc4c 100644
@@ -83,7 +83,7 @@
 #define MAX9611_TEMP_MAX_POS		0x7f80
 #define MAX9611_TEMP_MAX_NEG		0xff80
 #define MAX9611_TEMP_MIN_NEG		0xd980
-#define MAX9611_TEMP_MASK		GENMASK(7, 15)
+#define MAX9611_TEMP_MASK		GENMASK(15, 7)
 #define MAX9611_TEMP_SHIFT		0x07
 #define MAX9611_TEMP_RAW(_r)		((_r) >> MAX9611_TEMP_SHIFT)
 #define MAX9611_TEMP_SCALE_NUM		1000000
maintainer
#5 lore raw

Re: [PATCH 02/12] clocksource/drivers/npcm: Fix misuse of GENMASK macro

In reply to Joe Perches

Hi,
I noticed that this is totaly wrong, so I will fix here. If you wan I will put a separate patch.

Quoted 13 lines · Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/clocksource/timer-npcm7xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clocksource/timer-npcm7xx.c +0 -0
index 7a9bb5532d99..8a30da7f083b 100644

drivers/clocksource/timer-npcm7xx.c line 35

Quoted 5 lines
drivers/clocksource/timer-npcm7xx.c +1 -1
@@ -32,7 +32,7 @@
 #define NPCM7XX_Tx_INTEN               BIT(29)
 #define NPCM7XX_Tx_COUNTEN             BIT(30)
 #define NPCM7XX_Tx_ONESHOT             0x0
-#define NPCM7XX_Tx_OPER                        GENMASK(3, 27)
+#define NPCM7XX_Tx_OPER                        GENMASK(27, 3)

It should be:
+#define NPCM7XX_Tx_OPER GENMASK(28, 27)
but I need to do another change.

Quoted 6 lines
drivers/clocksource/timer-npcm7xx.c +0 -1
 #define NPCM7XX_Tx_MIN_PRESCALE                0x1
 #define NPCM7XX_Tx_TDR_MASK_BITS       24
 #define NPCM7XX_Tx_MAX_CNT             0xFFFFFF
--

2.15.0

Signature · 2 lines
Regards,
Avi
Reviewed-by on v1 10/12
#31 lore raw

Re: [PATCH 10/12] phy: amlogic: G12A: Fix misuse of GENMASK macro

In reply to Joe Perches
Quoted 13 lines · Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/phy/amlogic/phy-meson-g12a-usb2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/phy/amlogic/phy-meson-g12a-usb2.c +0 -0
index 9065ffc85eb4..cd7eccab2649 100644

drivers/phy/amlogic/phy-meson-g12a-usb2.c line 72

Quoted 8 lines
drivers/phy/amlogic/phy-meson-g12a-usb2.c +1 -1
@@ -66,7 +66,7 @@
 #define PHY_CTRL_R14						0x38
 	#define PHY_CTRL_R14_I_RDP_EN				BIT(0)
 	#define PHY_CTRL_R14_I_RPU_SW1_EN			BIT(1)
-	#define PHY_CTRL_R14_I_RPU_SW2_EN			GENMASK(2, 3)
+	#define PHY_CTRL_R14_I_RPU_SW2_EN			GENMASK(3, 2)
 	#define PHY_CTRL_R14_PG_RSTN				BIT(4)
 	#define PHY_CTRL_R14_I_C2L_DATA_16_8			BIT(5)
 	#define PHY_CTRL_R14_I_C2L_ASSERT_SINGLE_EN_ZERO	BIT(6)
Reviewed-by on v1 6/12
#22 lore raw

Re: [PATCH 06/12] mmc: meson-mx-sdio: Fix misuse of GENMASK macro

In reply to Joe Perches
Quoted 13 lines · Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/mmc/host/meson-mx-sdio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mmc/host/meson-mx-sdio.c +0 -0
index 2d736e416775..ba9a63db73da 100644

drivers/mmc/host/meson-mx-sdio.c line 79

Quoted 8 lines
drivers/mmc/host/meson-mx-sdio.c +1 -1
@@ -73,7 +73,7 @@
 	#define MESON_MX_SDIO_IRQC_IF_CONFIG_MASK		GENMASK(7, 6)
 	#define MESON_MX_SDIO_IRQC_FORCE_DATA_CLK		BIT(8)
 	#define MESON_MX_SDIO_IRQC_FORCE_DATA_CMD		BIT(9)
-	#define MESON_MX_SDIO_IRQC_FORCE_DATA_DAT_MASK		GENMASK(10, 13)
+	#define MESON_MX_SDIO_IRQC_FORCE_DATA_DAT_MASK		GENMASK(13, 10)
 	#define MESON_MX_SDIO_IRQC_SOFT_RESET			BIT(15)
 	#define MESON_MX_SDIO_IRQC_FORCE_HALT			BIT(30)
 	#define MESON_MX_SDIO_IRQC_HALT_HOLE			BIT(31)
maintainer
#42 lore raw

Applied "ASoC: wcd9335: Fix misuse of GENMASK macro" to the asoc tree

In reply to Joe Perches

The patch

ASoC: wcd9335: Fix misuse of GENMASK macro

has been applied to the asoc tree at

https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4

All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying to this mail.

Thanks,
Mark

Quoted 1 line

From f7408a3d5b5fd10571a653d1a81ce9167c62727f Mon Sep 17 00:00:00 2001

From: Joe Perches <[email protected]>
Date: Tue, 9 Jul 2019 22:04:25 -0700
Subject: [PATCH] ASoC: wcd9335: Fix misuse of GENMASK macro

Arguments are supposed to be ordered high then low.

---
 sound/soc/codecs/wcd-clsh-v2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/codecs/wcd-clsh-v2.c +1 -1
index c397d713f01a..cc5a9c9b918b 100644
@@ -65,7 +65,7 @@ struct wcd_clsh_ctrl {
 #define WCD9XXX_FLYBACK_EN_PWDN_WITH_DELAY			0
 #define WCD9XXX_RX_BIAS_FLYB_BUFF			WCD9335_REG(0x6, 0xC7)
 #define WCD9XXX_RX_BIAS_FLYB_VNEG_5_UA_MASK		GENMASK(7, 4)
-#define WCD9XXX_RX_BIAS_FLYB_VPOS_5_UA_MASK		GENMASK(0, 3)
+#define WCD9XXX_RX_BIAS_FLYB_VPOS_5_UA_MASK		GENMASK(3, 0)
 #define WCD9XXX_HPH_L_EN				WCD9335_REG(0x6, 0xD3)
 #define WCD9XXX_HPH_CONST_SEL_L_MASK			GENMASK(7, 3)
 #define WCD9XXX_HPH_CONST_SEL_BYPASS			0
Signature · 1 line
2.20.1
#23 lore raw

Re: [PATCH 06/12] mmc: meson-mx-sdio: Fix misuse of GENMASK macro

In reply to Joe Perches
Quoted 4 lines · Joe Perches

Arguments are supposed to be ordered high then low.

Applied for fixes by adding a fixes+stable tag, thanks!

Kind regards
Uffe

Quoted 20 lines
---
 drivers/mmc/host/meson-mx-sdio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mmc/host/meson-mx-sdio.c +1 -2
index 2d736e416775..ba9a63db73da 100644
@@ -73,7 +73,7 @@
        #define MESON_MX_SDIO_IRQC_IF_CONFIG_MASK               GENMASK(7, 6)
        #define MESON_MX_SDIO_IRQC_FORCE_DATA_CLK               BIT(8)
        #define MESON_MX_SDIO_IRQC_FORCE_DATA_CMD               BIT(9)
-       #define MESON_MX_SDIO_IRQC_FORCE_DATA_DAT_MASK          GENMASK(10, 13)
+       #define MESON_MX_SDIO_IRQC_FORCE_DATA_DAT_MASK          GENMASK(13, 10)
        #define MESON_MX_SDIO_IRQC_SOFT_RESET                   BIT(15)
        #define MESON_MX_SDIO_IRQC_FORCE_HALT                   BIT(30)
        #define MESON_MX_SDIO_IRQC_HALT_HOLE                    BIT(31)
--

2.15.0

#29 lore raw

Re: [PATCH 09/12] rtw88: Fix misuse of GENMASK macro

In reply to Joe Perches
Quoted 4 lines · Joe Perches

Arguments are supposed to be ordered high then low.

Patch applied to wireless-drivers-next.git, thanks.

5ff29d836d1b rtw88: Fix misuse of GENMASK macro

Signature · 3 lines
https://patchwork.kernel.org/patch/11037805/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
author maintainer
#36 lore raw

Re: [PATCH 11/12] staging: media: cedrus: Fix misuse of GENMASK macro

In reply to Joe Perches
Quoted 12 lines · Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/media/sunxi/cedrus/cedrus_regs.h +0 -0
index 3e9931416e45..ddd29788d685 100644

drivers/staging/media/sunxi/cedrus/cedrus_regs.h line 115

Quoted 7 lines
drivers/staging/media/sunxi/cedrus/cedrus_regs.h +1 -1
@@ -110,7 +110,7 @@
 #define VE_DEC_MPEG_MBADDR			(VE_ENGINE_DEC_MPEG + 0x10)
 
 #define VE_DEC_MPEG_MBADDR_X(w)			(((w) << 8) & GENMASK(15, 8))
-#define VE_DEC_MPEG_MBADDR_Y(h)			(((h) << 0) & GENMASK(0, 7))
+#define VE_DEC_MPEG_MBADDR_Y(h)			(((h) << 0) & GENMASK(7, 0))
 
 #define VE_DEC_MPEG_CTRL			(VE_ENGINE_DEC_MPEG + 0x14)

Greg? ping?

author maintainer
#7 lore raw

Re: [PATCH 03/12] drm: aspeed_gfx: Fix misuse of GENMASK macro

In reply to Joe Perches
Quoted 12 lines · Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/gpu/drm/aspeed/aspeed_gfx.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/aspeed/aspeed_gfx.h +0 -0
index a10358bb61ec..095ea03e5833 100644

drivers/gpu/drm/aspeed/aspeed_gfx.h int aspeed_gfx_create_output(struct drm_device *drm); · line 77

Quoted 5 lines
drivers/gpu/drm/aspeed/aspeed_gfx.h +1 -1
@@ -74,7 +74,7 @@ int aspeed_gfx_create_output(struct drm_device *drm);
 /* CTRL2 */
 #define CRT_CTRL_DAC_EN			BIT(0)
 #define CRT_CTRL_VBLANK_LINE(x)		(((x) << 20) & CRT_CTRL_VBLANK_LINE_MASK)
-#define CRT_CTRL_VBLANK_LINE_MASK	GENMASK(20, 31)
+#define CRT_CTRL_VBLANK_LINE_MASK	GENMASK(31, 20)

ping?

author maintainer
#2 lore raw

Re: [PATCH 01/12] checkpatch: Add GENMASK tests

In reply to Joe Perches
Quoted 7 lines · Joe Perches

This macro is easy to misuse as it's odd argument order.

If specified with simple decimal values, make sure the arguments are ordered high then low.

Also check if any argument is > 32 where instead of GENMASK, GENMASK_ULL should be used.

Hey Andrew, can you add this please.

Quoted 31 lines
---
 scripts/checkpatch.pl | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
scripts/checkpatch.pl +15 -0
index 6cb99ec62000..d37bbe33524b 100755
@@ -6368,6 +6368,21 @@ sub process {
 			     "switch default: should use break\n" . $herectx);
 		}
 
+# check for misuses of GENMASK
+		if ($line =~ /\b(GENMASK(?:_ULL)?)\s*\(\s*(\d+)\s*,\s*(\d+)\s*\)/) {
+			my $type = $1;
+			my $high = $2;
+			my $low = $3;
+			if ($high < $low) {
+				ERROR("GENMASK",
+				      "$type argument order is high then low\n" . $herecurr);
+			}
+			if ($type eq "GENMASK" && ($high >= 32 || $low >= 32)) {
+				ERROR("GENMASK",
+				      "$type with arguments >= 32 should use GENMASK_ULL\n" . $herecurr);
+			}
+		}
+
 # check for gcc specific __FUNCTION__
 		if ($line =~ /\b__FUNCTION__\b/) {
 			if (WARN("USE_FUNC",
#37 lore raw

Re: [PATCH 11/12] staging: media: cedrus: Fix misuse of GENMASK macro

In reply to Joe Perches
Quoted 15 lines · Joe Perches
Quoted 14 lines · Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/media/sunxi/cedrus/cedrus_regs.h +0 -0
index 3e9931416e45..ddd29788d685 100644
@@ -110,7 +110,7 @@
 #define VE_DEC_MPEG_MBADDR			(VE_ENGINE_DEC_MPEG + 0x10)
 
Quoted 9 lines

drivers/staging/media/sunxi/cedrus/cedrus_regs.h line 115

Quoted 5 lines
drivers/staging/media/sunxi/cedrus/cedrus_regs.h +1 -1
 #define VE_DEC_MPEG_MBADDR_X(w)			(((w) << 8) & GENMASK(15, 8))
-#define VE_DEC_MPEG_MBADDR_Y(h)			(((h) << 0) & GENMASK(0, 7))
+#define VE_DEC_MPEG_MBADDR_Y(h)			(((h) << 0) & GENMASK(7, 0))
 
 #define VE_DEC_MPEG_CTRL			(VE_ENGINE_DEC_MPEG + 0x14)

Greg? ping?

I am not the maintainer of drivers/staging/media, that is Mauro.

thanks,

greg k-h

author maintainer
#38 lore raw

Re: [PATCH 11/12] staging: media: cedrus: Fix misuse of GENMASK macro

Quoted 20 lines · Greg Kroah-Hartman
Quoted 19 lines · Joe Perches
Quoted 18 lines · Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/media/sunxi/cedrus/cedrus_regs.h +1 -1
index 3e9931416e45..ddd29788d685 100644
@@ -110,7 +110,7 @@
 #define VE_DEC_MPEG_MBADDR			(VE_ENGINE_DEC_MPEG + 0x10)
 
 #define VE_DEC_MPEG_MBADDR_X(w)			(((w) << 8) & GENMASK(15, 8))
-#define VE_DEC_MPEG_MBADDR_Y(h)			(((h) << 0) & GENMASK(0, 7))
+#define VE_DEC_MPEG_MBADDR_Y(h)			(((h) << 0) & GENMASK(7, 0))
 
Quoted 7 lines
Quoted 5 lines

drivers/staging/media/sunxi/cedrus/cedrus_regs.h line 115

Quoted 1 line
drivers/staging/media/sunxi/cedrus/cedrus_regs.h +0 -0
 #define VE_DEC_MPEG_CTRL			(VE_ENGINE_DEC_MPEG + 0x14)

Greg? ping?

I am not the maintainer of drivers/staging/media, that is Mauro.

Maybe you want:
---

MAINTAINERS +1 -0
index f7dc5bad396a..2fb95ad6ebef 100644
@@ -15312,6 +15312,7 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
 L:	[email protected]
 S:	Supported
 F:	drivers/staging/
+X:	drivers/staging/media/
 
 STARFIRE/DURALAN NETWORK DRIVER
 M:	Ion Badulescu <[email protected]>
#39 lore raw

Re: [PATCH 11/12] staging: media: cedrus: Fix misuse of GENMASK macro

Quoted 36 lines · Joe Perches
Quoted 20 lines · Greg Kroah-Hartman
Quoted 19 lines · Joe Perches
Quoted 18 lines · Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/media/sunxi/cedrus/cedrus_regs.h +1 -1
index 3e9931416e45..ddd29788d685 100644
@@ -110,7 +110,7 @@
 #define VE_DEC_MPEG_MBADDR			(VE_ENGINE_DEC_MPEG + 0x10)
 
 #define VE_DEC_MPEG_MBADDR_X(w)			(((w) << 8) & GENMASK(15, 8))
-#define VE_DEC_MPEG_MBADDR_Y(h)			(((h) << 0) & GENMASK(0, 7))
+#define VE_DEC_MPEG_MBADDR_Y(h)			(((h) << 0) & GENMASK(7, 0))
 
Quoted 7 lines
Quoted 5 lines

drivers/staging/media/sunxi/cedrus/cedrus_regs.h line 115

Quoted 1 line
drivers/staging/media/sunxi/cedrus/cedrus_regs.h +0 -0
 #define VE_DEC_MPEG_CTRL			(VE_ENGINE_DEC_MPEG + 0x14)

Greg? ping?

I am not the maintainer of drivers/staging/media, that is Mauro.

Maybe you want:
---

MAINTAINERS +0 -0
index f7dc5bad396a..2fb95ad6ebef 100644

MAINTAINERS T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git · line 15316

Quoted 5 lines
MAINTAINERS +1 -0
@@ -15312,6 +15312,7 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
 L:	[email protected]
 S:	Supported
 F:	drivers/staging/
+X:	drivers/staging/media/
 

Not really, it's nice to see the patches flow by :)

Reviewed-by
#8 lore raw

Re: [PATCH 03/12] drm: aspeed_gfx: Fix misuse of GENMASK macro

In reply to Joe Perches
Quoted 8 lines · Joe Perches
Quoted 7 lines · Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/gpu/drm/aspeed/aspeed_gfx.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Quoted 10 lines

drivers/gpu/drm/aspeed/aspeed_gfx.h int aspeed_gfx_create_output(struct drm_device *drm); · line 77

Quoted 10 lines
drivers/gpu/drm/aspeed/aspeed_gfx.h +1 -1
index a10358bb61ec..095ea03e5833 100644
@@ -74,7 +74,7 @@ int aspeed_gfx_create_output(struct drm_device *drm);
 /* CTRL2 */
 #define CRT_CTRL_DAC_EN			BIT(0)
 #define CRT_CTRL_VBLANK_LINE(x)		(((x) << 20) & CRT_CTRL_VBLANK_LINE_MASK)
-#define CRT_CTRL_VBLANK_LINE_MASK	GENMASK(20, 31)
+#define CRT_CTRL_VBLANK_LINE_MASK	GENMASK(31, 20)
Quoted 5 lines

ping?

_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

author maintainer
#9 lore raw

Re: [PATCH 03/12] drm: aspeed_gfx: Fix misuse of GENMASK macro

Quoted 10 lines · Andrew Jeffery
Quoted 8 lines · Joe Perches
Quoted 7 lines · Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/gpu/drm/aspeed/aspeed_gfx.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Quoted 12 lines
Quoted 10 lines

drivers/gpu/drm/aspeed/aspeed_gfx.h int aspeed_gfx_create_output(struct drm_device *drm); · line 77

Quoted 10 lines
drivers/gpu/drm/aspeed/aspeed_gfx.h +1 -1
index a10358bb61ec..095ea03e5833 100644
@@ -74,7 +74,7 @@ int aspeed_gfx_create_output(struct drm_device *drm);
 /* CTRL2 */
 #define CRT_CTRL_DAC_EN			BIT(0)
 #define CRT_CTRL_VBLANK_LINE(x)		(((x) << 20) & CRT_CTRL_VBLANK_LINE_MASK)
-#define CRT_CTRL_VBLANK_LINE_MASK	GENMASK(20, 31)
+#define CRT_CTRL_VBLANK_LINE_MASK	GENMASK(31, 20)

This hardly needs a review, it needs to be applied. There's a nominal git tree for aspeed here:

T: git git://git.kernel.org/pub/scm/linux/kernel/git/joel/aspeed.git

But who's going to do apply this?

maintainer
#10 lore raw

Re: [PATCH 03/12] drm: aspeed_gfx: Fix misuse of GENMASK macro

Quoted 25 lines · Joe Perches
Quoted 10 lines · Andrew Jeffery
Quoted 8 lines · Joe Perches
Quoted 7 lines · Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/gpu/drm/aspeed/aspeed_gfx.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Quoted 12 lines
Quoted 10 lines

drivers/gpu/drm/aspeed/aspeed_gfx.h int aspeed_gfx_create_output(struct drm_device *drm); · line 77

Quoted 10 lines
drivers/gpu/drm/aspeed/aspeed_gfx.h +1 -1
index a10358bb61ec..095ea03e5833 100644
@@ -74,7 +74,7 @@ int aspeed_gfx_create_output(struct drm_device *drm);
 /* CTRL2 */
 #define CRT_CTRL_DAC_EN                  BIT(0)
 #define CRT_CTRL_VBLANK_LINE(x)          (((x) << 20) & CRT_CTRL_VBLANK_LINE_MASK)
-#define CRT_CTRL_VBLANK_LINE_MASK        GENMASK(20, 31)
+#define CRT_CTRL_VBLANK_LINE_MASK        GENMASK(31, 20)
Quoted 6 lines

This hardly needs a review, it needs to be applied. There's a nominal git tree for aspeed here:

T: git git://git.kernel.org/pub/scm/linux/kernel/git/joel/aspeed.git

But who's going to do apply this?

This is a DRM patch, so it goes through the DRM tree. I am a co-maintainer there and can apply it once I remember how to drive the tools.

(FYI, this macro is not used by the current driver).

Cheers,

Joel

#40 lore raw

Re: [PATCH 11/12] staging: media: cedrus: Fix misuse of GENMASK macro

In reply to Joe Perches
Quoted 15 lines · Joe Perches
Quoted 14 lines · Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/media/sunxi/cedrus/cedrus_regs.h +0 -0
index 3e9931416e45..ddd29788d685 100644
@@ -110,7 +110,7 @@
 #define VE_DEC_MPEG_MBADDR			(VE_ENGINE_DEC_MPEG + 0x10)
 
Quoted 9 lines

drivers/staging/media/sunxi/cedrus/cedrus_regs.h line 115

Quoted 5 lines
drivers/staging/media/sunxi/cedrus/cedrus_regs.h +1 -1
 #define VE_DEC_MPEG_MBADDR_X(w)			(((w) << 8) & GENMASK(15, 8))
-#define VE_DEC_MPEG_MBADDR_Y(h)			(((h) << 0) & GENMASK(0, 7))
+#define VE_DEC_MPEG_MBADDR_Y(h)			(((h) << 0) & GENMASK(7, 0))
 
 #define VE_DEC_MPEG_CTRL			(VE_ENGINE_DEC_MPEG + 0x14)

Greg? ping?

It's actually me and I'm about to pick this one up and make a PR for Mauro.

Regards,

Hans

author maintainer
#11 lore raw

Re: [PATCH 03/12] drm: aspeed_gfx: Fix misuse of GENMASK macro

In reply to Joel Stanley
Quoted 29 lines · Joel Stanley
Quoted 28 lines · Joe Perches
Quoted 9 lines · Andrew Jeffery
Quoted 8 lines · Joe Perches
Quoted 7 lines · Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/gpu/drm/aspeed/aspeed_gfx.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Quoted 12 lines
Quoted 10 lines

drivers/gpu/drm/aspeed/aspeed_gfx.h int aspeed_gfx_create_output(struct drm_device *drm); · line 77

Quoted 10 lines
drivers/gpu/drm/aspeed/aspeed_gfx.h +1 -1
index a10358bb61ec..095ea03e5833 100644
@@ -74,7 +74,7 @@ int aspeed_gfx_create_output(struct drm_device *drm);
 /* CTRL2 */
 #define CRT_CTRL_DAC_EN                  BIT(0)
 #define CRT_CTRL_VBLANK_LINE(x)          (((x) << 20) & CRT_CTRL_VBLANK_LINE_MASK)
-#define CRT_CTRL_VBLANK_LINE_MASK        GENMASK(20, 31)
+#define CRT_CTRL_VBLANK_LINE_MASK        GENMASK(31, 20)

This hardly needs a review, it needs to be applied. There's a nominal git tree for aspeed here:

T: git git://git.kernel.org/pub/scm/linux/kernel/git/joel/aspeed.git

Quoted 7 lines
Quoted 1 line

But who's going to do apply this?

This is a DRM patch, so it goes through the DRM tree. I am a co-maintainer there and can apply it once I remember how to drive the tools.

(FYI, this macro is not used by the current driver).

Then perhaps CRT_CTRL_VBLANK and _MASK defines
should be removed instead.

cheers, Joe

#47 lore raw
In reply to Joe Perches

Trimming CC-list.

Quoted 3 lines

It'd can't be done as it's used in declarations
and included in asm files and it uses the UL()
macro.

Can the BUILD_BUG_ON_ZERO() macro be used instead? It works in declarations. I don't know if it works in asm-files, but the below changes builds an x86-64 allyesconfig without problems (after the rest of this series have been applied.

/Rikard

---
 include/linux/bits.h | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
include/linux/bits.h +7 -2
index 669d69441a62..52e747d27f87 100644
@@ -2,6 +2,7 @@
 #ifndef __LINUX_BITS_H
 #define __LINUX_BITS_H
 
+#include <linux/build_bug.h>
 #include <linux/const.h>
 #include <asm/bitsperlong.h>
 
@@ -19,11 +20,15 @@
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
 #define GENMASK(h, l) \
+	(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+		__is_constexpr(h) && __is_constexpr(l), (l) > (h), 0)) + \
 	(((~UL(0)) - (UL(1) << (l)) + 1) & \
-	 (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+	 (~UL(0) >> (BITS_PER_LONG - 1 - (h)))))
 
 #define GENMASK_ULL(h, l) \
+	(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+		__is_constexpr(h) && __is_constexpr(l), (l) > (h), 0)) + \
 	(((~ULL(0)) - (ULL(1) << (l)) + 1) & \
-	 (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+	 (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h)))))
 
 #endif	/* __LINUX_BITS_H */
Signature · 1 line
2.22.0
author maintainer
#48 lore raw
Quoted 10 lines · Rikard Falkeborn

Trimming CC-list.

Quoted 3 lines

It'd can't be done as it's used in declarations
and included in asm files and it uses the UL()
macro.

Can the BUILD_BUG_ON_ZERO() macro be used instead? It works in declarations. I don't know if it works in asm-files, but the below changes builds an x86-64 allyesconfig without problems (after the rest of this series have been applied.

Maybe, fine by me if it works.

Perhaps you should submit this and let the build-bot verify it.

Quoted 36 lines

/Rikard

---
 include/linux/bits.h | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
include/linux/bits.h +7 -2
index 669d69441a62..52e747d27f87 100644
@@ -2,6 +2,7 @@
 #ifndef __LINUX_BITS_H
 #define __LINUX_BITS_H
 
+#include <linux/build_bug.h>
 #include <linux/const.h>
 #include <asm/bitsperlong.h>
 
@@ -19,11 +20,15 @@
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
 #define GENMASK(h, l) \
+	(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+		__is_constexpr(h) && __is_constexpr(l), (l) > (h), 0)) + \
 	(((~UL(0)) - (UL(1) << (l)) + 1) & \
-	 (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+	 (~UL(0) >> (BITS_PER_LONG - 1 - (h)))))
 
 #define GENMASK_ULL(h, l) \
+	(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+		__is_constexpr(h) && __is_constexpr(l), (l) > (h), 0)) + \
 	(((~ULL(0)) - (ULL(1) << (l)) + 1) & \
-	 (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+	 (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h)))))
 
 #endif	/* __LINUX_BITS_H */
#16 lore raw

Re: [PATCH 04/12] iio: adc: max9611: Fix misuse of GENMASK macro

In reply to Joe Perches

Hello,
so I finally run some test and...

Quoted 10 lines · Joe Perches
Quoted 9 lines · Jonathan Cameron
Quoted 3 lines · On Tue, 9 Jul 2019 22:04:17 -0700 Joe Perches <[email protected]> wrote:

Arguments are supposed to be ordered high then low.

Applied to the fixes-togreg branch of iio.git and marked for stable etc.

I don't see it in v5.3-rc2, has it been collected or are we still in time for an additional fix?

Quoted 8 lines

This mask is used in an init function called from a probe.

I don't have this hardware but it looks as if it could never have worked so I doubt the driver and the hardware have ever been tested.

Does anyone have this device in actual use?

Because it turns out this is 2 times embarrassing. The mask definition is indeed wrong, as Joe reported and fixed, but also this line

Quoted 2 lines
	regval = ret & MAX9611_TEMP_MASK;

is very wrong as regval is read as:

        ret = max9611_read_single(max9611, CONF_TEMP, &regval);

So that should actually be:

        regval &= MAX9611_TEMP_MASK;

not
regval = ret & MAX9611_TEMP_MASK;
Ups...

Yes, it worked by chance, as regval was always 0, which is in the range of acceptable temperatures :/

Quoted 4 lines
	if ((regval > MAX9611_TEMP_MAX_POS &&
	     regval < MAX9611_TEMP_MIN_NEG) ||
	     regval > MAX9611_TEMP_MAX_NEG) {

Also reading this condition and how I had defined the temperature calculation formula makes me wonder if this it totally correct, but for the moment:

1) if Joe's patch has been collected, I can send an additional patch to fix how regval is computed.
2) If Joe's patch still have to be collected, the regval computation might be fixed there.

Sorry for taking so long to get back to you and thanks for noticing.

Thanks
j

Quoted 29 lines
		dev_err(max9611->dev,
			"Invalid value received from ADC 0x%4x: aborting\n",
			regval);
		return -EIO;
	}
Quoted 21 lines

Thanks,

Jonathan

Quoted 17 lines
---
 drivers/iio/adc/max9611.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/max9611.c +1 -1
index 917223d5ff5b..0e3c6529fc4c 100644
@@ -83,7 +83,7 @@
 #define MAX9611_TEMP_MAX_POS		0x7f80
 #define MAX9611_TEMP_MAX_NEG		0xff80
 #define MAX9611_TEMP_MIN_NEG		0xd980
-#define MAX9611_TEMP_MASK		GENMASK(7, 15)
+#define MAX9611_TEMP_MASK		GENMASK(15, 7)
 #define MAX9611_TEMP_SHIFT		0x07
 #define MAX9611_TEMP_RAW(_r)		((_r) >> MAX9611_TEMP_SHIFT)
 #define MAX9611_TEMP_SCALE_NUM		1000000
#17 lore raw

Re: [PATCH 04/12] iio: adc: max9611: Fix misuse of GENMASK macro

Quoted 49 lines · On Mon, 29 Jul 2019 23:52:14 +0200 Jacopo Mondi <[email protected]> wrote:

Hello,
so I finally run some test and...

Quoted 10 lines · Joe Perches
Quoted 9 lines · Jonathan Cameron
Quoted 3 lines · On Tue, 9 Jul 2019 22:04:17 -0700 Joe Perches <[email protected]> wrote:

Arguments are supposed to be ordered high then low.

Applied to the fixes-togreg branch of iio.git and marked for stable etc.

I don't see it in v5.3-rc2, has it been collected or are we still in time for an additional fix?

Quoted 8 lines

This mask is used in an init function called from a probe.

I don't have this hardware but it looks as if it could never have worked so I doubt the driver and the hardware have ever been tested.

Does anyone have this device in actual use?

Because it turns out this is 2 times embarrassing. The mask definition is indeed wrong, as Joe reported and fixed, but also this line

Quoted 2 lines
	regval = ret & MAX9611_TEMP_MASK;  

is very wrong as regval is read as:

        ret = max9611_read_single(max9611, CONF_TEMP, &regval);

So that should actually be:

        regval &= MAX9611_TEMP_MASK;

not
regval = ret & MAX9611_TEMP_MASK;
Ups...

Yes, it worked by chance, as regval was always 0, which is in the range of acceptable temperatures :/

Quoted 4 lines
	if ((regval > MAX9611_TEMP_MAX_POS &&
	     regval < MAX9611_TEMP_MIN_NEG) ||
	     regval > MAX9611_TEMP_MAX_NEG) {  
Quoted 8 lines

Also reading this condition and how I had defined the temperature calculation formula makes me wonder if this it totally correct, but for the moment:

1) if Joe's patch has been collected, I can send an additional patch to fix how regval is computed.
2) If Joe's patch still have to be collected, the regval computation might be fixed there.

I think this will have hit linux-next on the same day as your email.

https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/iio/adc?id=ae8cc91a7d85e018c0c267f580820b2bb558cd48

So follow up patch please.

Thanks!

Jonathan

Quoted 36 lines

Sorry for taking so long to get back to you and thanks for noticing.

Thanks
j

Quoted 29 lines
		dev_err(max9611->dev,
			"Invalid value received from ADC 0x%4x: aborting\n",
			regval);
		return -EIO;
	}
Quoted 21 lines

Thanks,

Jonathan

Quoted 17 lines
---
 drivers/iio/adc/max9611.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/max9611.c +1 -1
index 917223d5ff5b..0e3c6529fc4c 100644
@@ -83,7 +83,7 @@
 #define MAX9611_TEMP_MAX_POS		0x7f80
 #define MAX9611_TEMP_MAX_NEG		0xff80
 #define MAX9611_TEMP_MIN_NEG		0xd980
-#define MAX9611_TEMP_MASK		GENMASK(7, 15)
+#define MAX9611_TEMP_MASK		GENMASK(15, 7)
 #define MAX9611_TEMP_SHIFT		0x07
 #define MAX9611_TEMP_RAW(_r)		((_r) >> MAX9611_TEMP_SHIFT)
 #define MAX9611_TEMP_SCALE_NUM		1000000  
#49 lore raw

PATCH 1/1 linux/bits.h: Add compile time sanity check of GENMASK inputs

In reply to Joe Perches

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both the arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_OR_ZERO() must be used instead of BUILD_BUG_ON(), and __is_constexpr() must be used instead of __builtin_constant_p().

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since neither BUILD_BUG_OR_ZERO() or __is_constexpr() are asm compatible, disable the checks if the file is included in an asm file.

---
Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 7 of the patches were not in Linus tree, and 2 were not in linux-next.

Also, there's currently no asm users of bits.h, but since it was made asm-compatible just two weeks ago it would be a shame to break it right away...

 include/linux/bits.h | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
include/linux/bits.h +12 -2
index 669d69441a62..73489579eef9 100644
@@ -18,12 +18,22 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
+#ifndef __ASSEMBLY__
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l)  BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+		__is_constexpr(h) && __is_constexpr(l), (l) > (h), 0))
+#else
+#define GENMASK_INPUT_CHECK(h, l) 0
+#endif
+
 #define GENMASK(h, l) \
+	(GENMASK_INPUT_CHECK(h, l) + \
 	(((~UL(0)) - (UL(1) << (l)) + 1) & \
-	 (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+	 (~UL(0) >> (BITS_PER_LONG - 1 - (h)))))
 
 #define GENMASK_ULL(h, l) \
+	(GENMASK_INPUT_CHECK(h, l) + \
 	(((~ULL(0)) - (ULL(1) << (l)) + 1) & \
-	 (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+	 (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h)))))
 
 #endif	/* __LINUX_BITS_H */
Signature · 1 line
2.22.0
author maintainer
#50 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 24 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both the arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_OR_ZERO() must be used instead of BUILD_BUG_ON(), and __is_constexpr() must be used instead of __builtin_constant_p().

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since neither BUILD_BUG_OR_ZERO() or __is_constexpr() are asm compatible, disable the checks if the file is included in an asm file.

Quoted 8 lines

---
Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 7 of the patches were not in Linus tree, and 2 were not in linux-next.

Also, there's currently no asm users of bits.h, but since it was made asm-compatible just two weeks ago it would be a shame to break it right away...

[]

include/linux/bits.h

Quoted 1 line
include/linux/bits.h +0 -0

[]

include/linux/bits.h line 26

Quoted 10 lines
include/linux/bits.h +6 -0
@@ -18,12 +18,22 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
+#ifndef __ASSEMBLY__
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l)  BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+		__is_constexpr(h) && __is_constexpr(l), (l) > (h), 0))
+#else
+#define GENMASK_INPUT_CHECK(h, l) 0

A few things:

o Reading the final code is a bit confusing. Perhaps add a comment description saying it's not checked in asm .h uses.

o Maybe use:
#define GENMASK_INPUT_CHECK(h, l) UL(0)

o The compiler error message when the arguments are in the wrong order isn't obvious. Is there some way to improve the compiler error output, maybe by using BUILD_BUG_ON_MSG or some other mechanism?

#65 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

In reply to Rikard Falkeborn
Quoted 54 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both the arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_OR_ZERO() must be used instead of BUILD_BUG_ON(), and __is_constexpr() must be used instead of __builtin_constant_p().

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since neither BUILD_BUG_OR_ZERO() or __is_constexpr() are asm compatible, disable the checks if the file is included in an asm file.

---
Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 7 of the patches were not in Linus tree, and 2 were not in linux-next.

Also, there's currently no asm users of bits.h, but since it was made asm-compatible just two weeks ago it would be a shame to break it right away...

 include/linux/bits.h | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
include/linux/bits.h +8 -0
index 669d69441a62..73489579eef9 100644
@@ -18,12 +18,22 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
+#ifndef __ASSEMBLY__
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l)  BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+               __is_constexpr(h) && __is_constexpr(l), (l) > (h), 0))
+#else
+#define GENMASK_INPUT_CHECK(h, l) 0
+#endif
+
 #define GENMASK(h, l) \

include/linux/bits.h line 37

Quoted 10 lines
include/linux/bits.h +4 -2
+       (GENMASK_INPUT_CHECK(h, l) + \
        (((~UL(0)) - (UL(1) << (l)) + 1) & \
-        (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+        (~UL(0) >> (BITS_PER_LONG - 1 - (h)))))
 
 #define GENMASK_ULL(h, l) \
+       (GENMASK_INPUT_CHECK(h, l) + \
        (((~ULL(0)) - (ULL(1) << (l)) + 1) & \
-        (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+        (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h)))))

This is getting cluttered with so many parentheses.

One way of clean-up is to rename the current macros as follows:

GENMASK() -> __GENMASK()
GENMASK_UL() -> __GENMASK_ULL()

Then,

#define GENMASK(h, l) (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
#define GENMASK_ULL(h, l) (GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))

Signature · 2 lines
Best Regards
Masahiro Yamada
author maintainer
#66 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 31 lines · Masahiro Yamada
Quoted 29 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both the arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_OR_ZERO() must be used instead of BUILD_BUG_ON(), and __is_constexpr() must be used instead of __builtin_constant_p().

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since neither BUILD_BUG_OR_ZERO() or __is_constexpr() are asm compatible, disable the checks if the file is included in an asm file.

---
Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 7 of the patches were not in Linus tree, and 2 were not in linux-next.

Quoted 3 lines
Quoted 3 lines

Also, there's currently no asm users of bits.h, but since it was made asm-compatible just two weeks ago it would be a shame to break it right away...

[]

Quoted 1 line

include/linux/bits.h

Quoted 1 line
include/linux/bits.h +0 -0

[]

Quoted 16 lines

include/linux/bits.h line 37

Quoted 11 lines

#define GENMASK(h, l) \

include/linux/bits.h +4 -2
+       (GENMASK_INPUT_CHECK(h, l) + \
        (((~UL(0)) - (UL(1) << (l)) + 1) & \
-        (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+        (~UL(0) >> (BITS_PER_LONG - 1 - (h)))))
 
 #define GENMASK_ULL(h, l) \
+       (GENMASK_INPUT_CHECK(h, l) + \
        (((~ULL(0)) - (ULL(1) << (l)) + 1) & \
-        (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+        (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h)))))

This is getting cluttered with so many parentheses.

One way of clean-up is to rename the current macros as follows:

Quoted 7 lines
   GENMASK()    ->  __GENMASK()
   GENMASK_UL() ->  __GENMASK_ULL()

Then,

#define GENMASK(h, l) (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
#define GENMASK_ULL(h, l) (GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))

Much nicer. It may be better still to use avoid
multiple dereferences of each argument.

Also it'd be useful to rename h and l to something like high_bit and low_bit or high and low.

#51 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

In reply to Joe Perches
Quoted 10 lines · Joe Perches
Quoted 3 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

A few things:

o Reading the final code is a bit confusing. Perhaps add a comment description saying it's not checked in asm .h uses.

Comment added.

Quoted 2 lines

o Maybe use:
#define GENMASK_INPUT_CHECK(h, l) UL(0)

Sure.

Quoted 4 lines

o The compiler error message when the arguments are in the wrong order isn't obvious. Is there some way to improve the compiler error output, maybe by using BUILD_BUG_ON_MSG or some other mechanism?

Not that I could find. BUILD_BUG_ON_MSG can not be used if the macros should be usable in e.g. a structure initializer (this seems to be the whole reason BUILD_BUG_ON_ZERO exists).

#67 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

In reply to Joe Perches
Quoted 14 lines · Joe Perches
Quoted 13 lines · Masahiro Yamada
Quoted 3 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

This is getting cluttered with so many parentheses.

One way of clean-up is to rename the current macros as follows:

   GENMASK()    ->  __GENMASK()
   GENMASK_UL() ->  __GENMASK_ULL()
Quoted 7 lines
Quoted 4 lines

Then,

#define GENMASK(h, l) (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
#define GENMASK_ULL(h, l) (GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))

Much nicer. It may be better still to use avoid
multiple dereferences of each argument.

Much nicer indeed, I changed it accordingly. There are no multiple dererences of the arguments. GENMASK_INPUT_CHECK() and __is_constexpr() both use sizeof() on the input arguments, which does not evaluate the argument (unless the argument is a VLA, which is not allowed).

Quoted 2 lines

Also it'd be useful to rename h and l to something like high_bit and low_bit or high and low.

Agreed.

#68 lore raw

PATCH v2 1/2 linux/bits.h: Clarify macro argument names

In reply to Rikard Falkeborn

Be a little more verbose to improve readability.

---
Changes in v2:
- This patch is new in v2

 include/linux/bits.h | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
include/linux/bits.h +8 -8
index 669d69441a62..d4466aa42a9c 100644
@@ -14,16 +14,16 @@
 #define BITS_PER_BYTE		8
 
 /*
- * Create a contiguous bitmask starting at bit position @l and ending at
- * position @h. For example
+ * Create a contiguous bitmask starting at bit position @low and ending at
+ * position @high. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(h, l) \
-	(((~UL(0)) - (UL(1) << (l)) + 1) & \
-	 (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+#define GENMASK(high, low) \
+	(((~UL(0)) - (UL(1) << (low)) + 1) & \
+	 (~UL(0) >> (BITS_PER_LONG - 1 - (high))))
 
-#define GENMASK_ULL(h, l) \
-	(((~ULL(0)) - (ULL(1) << (l)) + 1) & \
-	 (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+#define GENMASK_ULL(high, low) \
+	(((~ULL(0)) - (ULL(1) << (low)) + 1) & \
+	 (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (high))))
 
 #endif	/* __LINUX_BITS_H */
Signature · 1 line
2.22.0
#69 lore raw

PATCH v2 2/2 linux/bits.h: Add compile time sanity check of GENMASK inputs

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both the arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON(), and __is_constexpr() must be used instead of __builtin_constant_p().

If successful, BUILD_BUG_OR_ZERO() returns 0 of type size_t. To avoid problems with implicit conversions, cast the result of BUILD_BUG_OR_ZERO to unsigned long.

Since both BUILD_BUG_ON_ZERO() and __is_constexpr() only uses sizeof() on the arguments passed to them, neither of them evaluate the expression unless it is a VLA. Therefore, GENMASK(1, x++) still behaves as expected.

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since neither BUILD_BUG_OR_ZERO() or __is_constexpr() are asm compatible, disable the checks if the file is included in an asm file.

---
Changes in v2:
- Add comment about why inputs are not checked when used in asm file
- Use UL(0) instead of 0
- Extract mask creation in a separate macro to improve readability
- Use high and low instead of h and l (part of this was extracted to a separate patch)
- Updated commit message

Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 6 of the patches are not in Linus tree, and 2 are not in linux-next.

 include/linux/bits.h | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)
include/linux/bits.h +20 -2
index d4466aa42a9c..955e9e43c4a5 100644
@@ -18,12 +18,30 @@
  * position @high. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(high, low) \
+#ifndef __ASSEMBLY__
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(high, low) \
+	((unsigned long)BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+		__is_constexpr(high) && __is_constexpr(low), \
+		(low) > (high), UL(0))))
+#else
+/*
+ * BUILD_BUG_ON_ZERO and __is_constexpr() are not available in h files
+ * included from asm files, disable the input check if that is the case.
+ */
+#define GENMASK_INPUT_CHECK(high, low) UL(0)
+#endif
+
+#define __GENMASK(high, low) \
 	(((~UL(0)) - (UL(1) << (low)) + 1) & \
 	 (~UL(0) >> (BITS_PER_LONG - 1 - (high))))
+#define GENMASK(high, low) \
+	(GENMASK_INPUT_CHECK(high, low) + __GENMASK(high, low))
 
-#define GENMASK_ULL(high, low) \
+#define __GENMASK_ULL(high, low) \
 	(((~ULL(0)) - (ULL(1) << (low)) + 1) & \
 	 (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (high))))
+#define GENMASK_ULL(high, low) \
+	(GENMASK_INPUT_CHECK(high, low) + __GENMASK_ULL(high, low))
 
 #endif	/* __LINUX_BITS_H */
Signature · 1 line
2.22.0
author maintainer
#70 lore raw

Re: [PATCH v2 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 42 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both the arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON(), and __is_constexpr() must be used instead of __builtin_constant_p().

If successful, BUILD_BUG_OR_ZERO() returns 0 of type size_t. To avoid problems with implicit conversions, cast the result of BUILD_BUG_OR_ZERO to unsigned long.

Since both BUILD_BUG_ON_ZERO() and __is_constexpr() only uses sizeof() on the arguments passed to them, neither of them evaluate the expression unless it is a VLA. Therefore, GENMASK(1, x++) still behaves as expected.

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since neither BUILD_BUG_OR_ZERO() or __is_constexpr() are asm compatible, disable the checks if the file is included in an asm file.

---
Changes in v2:
- Add comment about why inputs are not checked when used in asm file
- Use UL(0) instead of 0
- Extract mask creation in a separate macro to improve readability
- Use high and low instead of h and l (part of this was extracted to a separate patch)
- Updated commit message

Quoted 3 lines

Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 6 of the patches are not in Linus tree, and 2 are not in linux-next.

Thanks Rikard.

It wouldn't surprise me if this change finds more misuses as the compiler will perform substitutions on #define values where the search I did was just for decimal uses.

For instance, this new macro should build error on:

#define FOO 5
#define BAR 6

GENMASK(FOO, BAR)

#52 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

In reply to Joe Perches
Quoted 50 lines · Joe Perches
Quoted 24 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both the arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_OR_ZERO() must be used instead of BUILD_BUG_ON(), and __is_constexpr() must be used instead of __builtin_constant_p().

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since neither BUILD_BUG_OR_ZERO() or __is_constexpr() are asm compatible, disable the checks if the file is included in an asm file.

Quoted 8 lines

---
Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 7 of the patches were not in Linus tree, and 2 were not in linux-next.

Also, there's currently no asm users of bits.h, but since it was made asm-compatible just two weeks ago it would be a shame to break it right away...

[]

include/linux/bits.h

Quoted 1 line
include/linux/bits.h +0 -0

[]

include/linux/bits.h line 26

Quoted 10 lines
include/linux/bits.h +6 -0
@@ -18,12 +18,22 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
+#ifndef __ASSEMBLY__
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l)  BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+             __is_constexpr(h) && __is_constexpr(l), (l) > (h), 0))
+#else
+#define GENMASK_INPUT_CHECK(h, l) 0

A few things:

Quoted 6 lines

o Reading the final code is a bit confusing. Perhaps add a comment description saying it's not checked in asm .h uses.

o Maybe use:
#define GENMASK_INPUT_CHECK(h, l) UL(0)

Why?

Quoted 6 lines

o The compiler error message when the arguments are in the wrong order isn't obvious. Is there some way to improve the compiler error output, maybe by using BUILD_BUG_ON_MSG or some other mechanism?

Signature · 2 lines
Best Regards
Masahiro Yamada
author maintainer
#53 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 50 lines · Masahiro Yamada
Quoted 49 lines · Joe Perches
Quoted 24 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both the arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_OR_ZERO() must be used instead of BUILD_BUG_ON(), and __is_constexpr() must be used instead of __builtin_constant_p().

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since neither BUILD_BUG_OR_ZERO() or __is_constexpr() are asm compatible, disable the checks if the file is included in an asm file.

Quoted 8 lines

---
Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 7 of the patches were not in Linus tree, and 2 were not in linux-next.

Also, there's currently no asm users of bits.h, but since it was made asm-compatible just two weeks ago it would be a shame to break it right away...

[]

include/linux/bits.h

Quoted 1 line
include/linux/bits.h +0 -0

[]

include/linux/bits.h line 26

Quoted 10 lines
include/linux/bits.h +6 -0
@@ -18,12 +18,22 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
+#ifndef __ASSEMBLY__
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l)  BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+             __is_constexpr(h) && __is_constexpr(l), (l) > (h), 0))
+#else
+#define GENMASK_INPUT_CHECK(h, l) 0

A few things:

Quoted 8 lines
Quoted 6 lines

o Reading the final code is a bit confusing. Perhaps add a comment description saying it's not checked in asm .h uses.

o Maybe use:
#define GENMASK_INPUT_CHECK(h, l) UL(0)

Why?

Consistency with the uses in what's now called __GENMASK

#54 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 56 lines · Joe Perches
Quoted 54 lines · Masahiro Yamada
Quoted 53 lines · Joe Perches
Quoted 24 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both the arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_OR_ZERO() must be used instead of BUILD_BUG_ON(), and __is_constexpr() must be used instead of __builtin_constant_p().

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since neither BUILD_BUG_OR_ZERO() or __is_constexpr() are asm compatible, disable the checks if the file is included in an asm file.

Quoted 8 lines

---
Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 7 of the patches were not in Linus tree, and 2 were not in linux-next.

Also, there's currently no asm users of bits.h, but since it was made asm-compatible just two weeks ago it would be a shame to break it right away...

[]

include/linux/bits.h

Quoted 1 line
include/linux/bits.h +0 -0

[]

include/linux/bits.h line 26

Quoted 10 lines
include/linux/bits.h +6 -0
@@ -18,12 +18,22 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
+#ifndef __ASSEMBLY__
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l)  BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+             __is_constexpr(h) && __is_constexpr(l), (l) > (h), 0))
+#else
+#define GENMASK_INPUT_CHECK(h, l) 0

A few things:

o Reading the final code is a bit confusing. Perhaps add a comment description saying it's not checked in asm .h uses.

Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

o Maybe use:
#define GENMASK_INPUT_CHECK(h, l) UL(0)

Why?

Consistency with the uses in what's now called __GENMASK

Inconsistent with __GENMASK_ULL.

Signature · 2 lines
Best Regards
Masahiro Yamada
#55 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 57 lines · Masahiro Yamada
Quoted 56 lines · Joe Perches
Quoted 54 lines · Masahiro Yamada
Quoted 53 lines · Joe Perches
Quoted 24 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both the arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_OR_ZERO() must be used instead of BUILD_BUG_ON(), and __is_constexpr() must be used instead of __builtin_constant_p().

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since neither BUILD_BUG_OR_ZERO() or __is_constexpr() are asm compatible, disable the checks if the file is included in an asm file.

Quoted 8 lines

---
Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 7 of the patches were not in Linus tree, and 2 were not in linux-next.

Also, there's currently no asm users of bits.h, but since it was made asm-compatible just two weeks ago it would be a shame to break it right away...

[]

include/linux/bits.h

Quoted 1 line
include/linux/bits.h +0 -0

[]

include/linux/bits.h line 26

Quoted 10 lines
include/linux/bits.h +6 -0
@@ -18,12 +18,22 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
+#ifndef __ASSEMBLY__
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l)  BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+             __is_constexpr(h) && __is_constexpr(l), (l) > (h), 0))
+#else
+#define GENMASK_INPUT_CHECK(h, l) 0

A few things:

o Reading the final code is a bit confusing. Perhaps add a comment description saying it's not checked in asm .h uses.

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

o Maybe use:
#define GENMASK_INPUT_CHECK(h, l) UL(0)

Why?

Consistency with the uses in what's now called __GENMASK

Inconsistent with __GENMASK_ULL.

Would you prefer to add GENMASK_ULL_INPUT_CHECK? Or replace UL(0) with 0 and then probably move the cast of BUILD_BUG_OR_ZERO (to avoid GENMASK be of type size_t) to GENMASK and GENMASK_ULL?

#56 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 62 lines · Rikard Falkeborn
Quoted 60 lines · Masahiro Yamada
Quoted 59 lines · Joe Perches
Quoted 57 lines · Masahiro Yamada
Quoted 55 lines · Joe Perches
Quoted 24 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both the arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_OR_ZERO() must be used instead of BUILD_BUG_ON(), and __is_constexpr() must be used instead of __builtin_constant_p().

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since neither BUILD_BUG_OR_ZERO() or __is_constexpr() are asm compatible, disable the checks if the file is included in an asm file.

Quoted 8 lines

---
Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 7 of the patches were not in Linus tree, and 2 were not in linux-next.

Also, there's currently no asm users of bits.h, but since it was made asm-compatible just two weeks ago it would be a shame to break it right away...

[]

include/linux/bits.h

Quoted 1 line
include/linux/bits.h +0 -0

[]

include/linux/bits.h line 26

Quoted 10 lines
include/linux/bits.h +6 -0
@@ -18,12 +18,22 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
+#ifndef __ASSEMBLY__
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l)  BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+             __is_constexpr(h) && __is_constexpr(l), (l) > (h), 0))
+#else
+#define GENMASK_INPUT_CHECK(h, l) 0

A few things:

o Reading the final code is a bit confusing. Perhaps add a comment description saying it's not checked in asm .h uses.

o Maybe use:
#define GENMASK_INPUT_CHECK(h, l) UL(0)

Quoted 7 lines
Quoted 5 lines
Quoted 3 lines
Quoted 1 line

Why?

Consistency with the uses in what's now called __GENMASK

Inconsistent with __GENMASK_ULL.

Would you prefer to add GENMASK_ULL_INPUT_CHECK?

No.

Quoted 3 lines

Or replace UL(0) with
0 and then probably move the cast of BUILD_BUG_OR_ZERO (to avoid GENMASK be of type size_t) to GENMASK and GENMASK_ULL?

No.

Your original code is absolutely fine.

C aligns the types to the wider one.

(unsigned long)      + (int)  ->  (unsigned long)
(unsigned long long) + (int)  ->  (unsigned long long)

Having GENMASK_INPUT_CHECK to return 'int' is OK. The resulted GENMASK(), GENMASK_ULL() still have unsigned long, unsigned long long, respectively.

BTW, v2 is already inconsistent.
If you wanted GENMASK_INPUT_CHECK() to return 'unsigned long',, you would have to cast (low) > (high) as well:

               (unsigned long)((low) > (high)), UL(0))))

This is totally redundant, and weird.

Signature · 2 lines
Best Regards
Masahiro Yamada
#57 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 8 lines · Masahiro Yamada

BTW, v2 is already inconsistent.
If you wanted GENMASK_INPUT_CHECK() to return 'unsigned long',, you would have to cast (low) > (high) as well:

               (unsigned long)((low) > (high)), UL(0))))

This is totally redundant, and weird.

I take back this comment.
You added (unsigned long) to the beginning of this macro. So, the type is consistent, but I believe all casts should be removed.

Signature · 2 lines
Best Regards
Masahiro Yamada
#58 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 8 lines · Masahiro Yamada
Quoted 5 lines · Masahiro Yamada

BTW, v2 is already inconsistent.
If you wanted GENMASK_INPUT_CHECK() to return 'unsigned long',, you would have to cast (low) > (high) as well:

Quoted 7 lines
Quoted 3 lines
               (unsigned long)((low) > (high)), UL(0))))

This is totally redundant, and weird.

I take back this comment.
You added (unsigned long) to the beginning of this macro. So, the type is consistent, but I believe all casts should be removed.

Maybe you're right. BUILD_BUG_ON_ZERO returns size_t regardless of inputs. I was worried that on some platform, size_t would be larger than unsigned long (as far as I could see, the standard does not give any guarantees), and thus all of a sudden GENMASK would be 8 bytes instead of 4, but perhaps that is not a problem?

#59 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 18 lines · Rikard Falkeborn
Quoted 8 lines · Masahiro Yamada
Quoted 5 lines · Masahiro Yamada

BTW, v2 is already inconsistent.
If you wanted GENMASK_INPUT_CHECK() to return 'unsigned long',, you would have to cast (low) > (high) as well:

Quoted 7 lines
Quoted 3 lines
               (unsigned long)((low) > (high)), UL(0))))

This is totally redundant, and weird.

I take back this comment.
You added (unsigned long) to the beginning of this macro. So, the type is consistent, but I believe all casts should be removed.

Quoted 5 lines

Maybe you're right. BUILD_BUG_ON_ZERO returns size_t regardless of inputs. I was worried that on some platform, size_t would be larger than unsigned long (as far as I could see, the standard does not give any guarantees), and thus all of a sudden GENMASK would be 8 bytes instead of 4, but perhaps that is not a problem?

How about adding (int) cast to BUILD_BUG_ON_ZERO() ?

Signature · 2 lines
Best Regards
Masahiro Yamada
#60 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 20 lines · Masahiro Yamada
Quoted 18 lines · Rikard Falkeborn
Quoted 15 lines · Masahiro Yamada
Quoted 8 lines · Masahiro Yamada

BTW, v2 is already inconsistent.
If you wanted GENMASK_INPUT_CHECK() to return 'unsigned long',, you would have to cast (low) > (high) as well:

               (unsigned long)((low) > (high)), UL(0))))

This is totally redundant, and weird.

I take back this comment.
You added (unsigned long) to the beginning of this macro. So, the type is consistent, but I believe all casts should be removed.

Quoted 8 lines
Quoted 5 lines

Maybe you're right. BUILD_BUG_ON_ZERO returns size_t regardless of inputs. I was worried that on some platform, size_t would be larger than unsigned long (as far as I could see, the standard does not give any guarantees), and thus all of a sudden GENMASK would be 8 bytes instead of 4, but perhaps that is not a problem?

How about adding (int) cast to BUILD_BUG_ON_ZERO() ?

I'll have a look.

#61 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

Hi Rikard,

Quoted 29 lines · Rikard Falkeborn
Quoted 27 lines · Masahiro Yamada
Quoted 23 lines · Rikard Falkeborn
Quoted 8 lines · Masahiro Yamada
Quoted 5 lines · Masahiro Yamada

BTW, v2 is already inconsistent.
If you wanted GENMASK_INPUT_CHECK() to return 'unsigned long',, you would have to cast (low) > (high) as well:

Quoted 7 lines
Quoted 3 lines
               (unsigned long)((low) > (high)), UL(0))))

This is totally redundant, and weird.

I take back this comment.
You added (unsigned long) to the beginning of this macro. So, the type is consistent, but I believe all casts should be removed.

Maybe you're right. BUILD_BUG_ON_ZERO returns size_t regardless of inputs. I was worried that on some platform, size_t would be larger than unsigned long (as far as I could see, the standard does not give any guarantees), and thus all of a sudden GENMASK would be 8 bytes instead of 4, but perhaps that is not a problem?

Quoted 3 lines
Quoted 1 line

How about adding (int) cast to BUILD_BUG_ON_ZERO() ?

I'll have a look.

I found a more important problem in this patch.

You used __is_constexpr(), which is defined in <linux/kernel.h>.

This header does not include <linux/kernel.h>,
so this header is not self-contained anymore.

The following test code fails to build:

#include <linux/bits.h>
unsigned long foo(unsigned long in_bits)

{
        return in_bits & GENMASK(5, 3);
}

However, you cannot include <linux/kernel.h> from <linux/bits.h>. See the log of 8bd9cb51daac89337295b6f037b0486911e1b408

This header was split out to not pull in <linux/bitops.h> Including <linux/kernel.h> pulls in <linux/bitops.h> again.

In summary, please use __builtin_constant_p()
instead of __is_constexpr().

You can shorten __builtin_constant_p(high) && __builtin_constant_p(low) into __builtin_constant_p((low) > (high)).

How about this?

#define GENMASK_INPUT_CHECK(high, low) \
       BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
              __builtin_constant_p((low) > (high)), (low) > (high), 0))
Signature · 2 lines
Best Regards
Masahiro Yamada
#62 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

Hi Masahiro,

Quoted 72 lines · Masahiro Yamada

Hi Rikard,

Quoted 29 lines · Rikard Falkeborn
Quoted 27 lines · Masahiro Yamada
Quoted 23 lines · Rikard Falkeborn
Quoted 8 lines · Masahiro Yamada
Quoted 5 lines · Masahiro Yamada

BTW, v2 is already inconsistent.
If you wanted GENMASK_INPUT_CHECK() to return 'unsigned long',, you would have to cast (low) > (high) as well:

Quoted 7 lines
Quoted 3 lines
               (unsigned long)((low) > (high)), UL(0))))

This is totally redundant, and weird.

I take back this comment.
You added (unsigned long) to the beginning of this macro. So, the type is consistent, but I believe all casts should be removed.

Maybe you're right. BUILD_BUG_ON_ZERO returns size_t regardless of inputs. I was worried that on some platform, size_t would be larger than unsigned long (as far as I could see, the standard does not give any guarantees), and thus all of a sudden GENMASK would be 8 bytes instead of 4, but perhaps that is not a problem?

Quoted 3 lines
Quoted 1 line

How about adding (int) cast to BUILD_BUG_ON_ZERO() ?

I'll have a look.

I found a more important problem in this patch.

You used __is_constexpr(), which is defined in <linux/kernel.h>.

This header does not include <linux/kernel.h>,
so this header is not self-contained anymore.

The following test code fails to build:

#include <linux/bits.h>
unsigned long foo(unsigned long in_bits)

{
        return in_bits & GENMASK(5, 3);
}

However, you cannot include <linux/kernel.h> from <linux/bits.h>. See the log of 8bd9cb51daac89337295b6f037b0486911e1b408

This header was split out to not pull in <linux/bitops.h> Including <linux/kernel.h> pulls in <linux/bitops.h> again.

In summary, please use __builtin_constant_p()
instead of __is_constexpr().

You can shorten __builtin_constant_p(high) && __builtin_constant_p(low) into __builtin_constant_p((low) > (high)).

Quoted 11 lines

How about this?

#define GENMASK_INPUT_CHECK(high, low) \
       BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
              __builtin_constant_p((low) > (high)), (low) > (high), 0))
Signature · 2 lines
Best Regards
Masahiro Yamada

Thanks for the feedback, your version looks much cleaner than mine. I *think* I had a reason for using __is_constexpr() instead of __builtin_constant_p but I'll try a full rebuild to see if something comes up.

Best Regards,
Rikard Falkeborn

author maintainer
#63 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 9 lines · Rikard Falkeborn
Quoted 4 lines · Masahiro Yamada

How about this?

#define GENMASK_INPUT_CHECK(high, low) \
       BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
              __builtin_constant_p((low) > (high)), (low) > (high), 0))

Thanks for the feedback, your version looks much cleaner than mine. I *think* I had a reason for using __is_constexpr() instead of __builtin_constant_p but I'll try a full rebuild to see if something comes up.

Perhaps a statement expression so high and low aren't possibly evaluated multiple times?

#define GENMASK_INPUT_CHECK(high, low) \

({								\
	typeof(high) _high = high;				\
	typeof(low) _low = low;					\
	BUILD_BUG_ON_ZERO(__builtin_constant_p(_low > _high,	\
					       _low > _high,	\
					       0))		\
})
#71 lore raw

Re: [PATCH v2 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs

In reply to Rikard Falkeborn
Quoted 27 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both the arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON(), and __is_constexpr() must be used instead of __builtin_constant_p().

If successful, BUILD_BUG_OR_ZERO() returns 0 of type size_t. To avoid problems with implicit conversions, cast the result of BUILD_BUG_OR_ZERO to unsigned long.

Since both BUILD_BUG_ON_ZERO() and __is_constexpr() only uses sizeof() on the arguments passed to them, neither of them evaluate the expression unless it is a VLA. Therefore, GENMASK(1, x++) still behaves as expected.

Quoted 5 lines

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since neither BUILD_BUG_OR_ZERO() or __is_constexpr() are asm compatible, disable the checks if the file is included in an asm file.

Who is going to fix the fallout ? For example, arm64:defconfig no longer compiles with this patch applied.

It seems to me that the benefit of catching misuses of GENMASK is much less than the fallout from no longer compiling kernels, since those kernels won't get any test coverage at all anymore.

Guenter

#72 lore raw

Re: [PATCH v2 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 35 lines · Guenter Roeck
Quoted 27 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both the arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON(), and __is_constexpr() must be used instead of __builtin_constant_p().

If successful, BUILD_BUG_OR_ZERO() returns 0 of type size_t. To avoid problems with implicit conversions, cast the result of BUILD_BUG_OR_ZERO to unsigned long.

Since both BUILD_BUG_ON_ZERO() and __is_constexpr() only uses sizeof() on the arguments passed to them, neither of them evaluate the expression unless it is a VLA. Therefore, GENMASK(1, x++) still behaves as expected.

Quoted 5 lines

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since neither BUILD_BUG_OR_ZERO() or __is_constexpr() are asm compatible, disable the checks if the file is included in an asm file.

Quoted 6 lines

Who is going to fix the fallout ? For example, arm64:defconfig no longer compiles with this patch applied.

It seems to me that the benefit of catching misuses of GENMASK is much less than the fallout from no longer compiling kernels, since those kernels won't get any test coverage at all anymore.

We cannot apply this until we fix all errors.

I do not understand why Andrew picked up this so soon.

Signature · 2 lines
Best Regards
Masahiro Yamada
#73 lore raw

Re: [PATCH v2 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 39 lines · Masahiro Yamada
Quoted 38 lines · Guenter Roeck
Quoted 27 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both the arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON(), and __is_constexpr() must be used instead of __builtin_constant_p().

If successful, BUILD_BUG_OR_ZERO() returns 0 of type size_t. To avoid problems with implicit conversions, cast the result of BUILD_BUG_OR_ZERO to unsigned long.

Since both BUILD_BUG_ON_ZERO() and __is_constexpr() only uses sizeof() on the arguments passed to them, neither of them evaluate the expression unless it is a VLA. Therefore, GENMASK(1, x++) still behaves as expected.

Quoted 5 lines

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since neither BUILD_BUG_OR_ZERO() or __is_constexpr() are asm compatible, disable the checks if the file is included in an asm file.

Who is going to fix the fallout ? For example, arm64:defconfig no longer compiles with this patch applied.

Quoted 9 lines
Quoted 3 lines

It seems to me that the benefit of catching misuses of GENMASK is much less than the fallout from no longer compiling kernels, since those kernels won't get any test coverage at all anymore.

We cannot apply this until we fix all errors.

I do not understand why Andrew picked up this so soon.

The same was done with the fallthrough warning in mainline, which still results in all "sh" builds failing there (and in -next, obviously). I don't understand the logic either, but maybe it is the new normal.

Guenter

#74 lore raw

Re: [PATCH v2 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 47 lines · Guenter Roeck
Quoted 46 lines · Masahiro Yamada
Quoted 35 lines · Guenter Roeck
Quoted 27 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both the arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON(), and __is_constexpr() must be used instead of __builtin_constant_p().

If successful, BUILD_BUG_OR_ZERO() returns 0 of type size_t. To avoid problems with implicit conversions, cast the result of BUILD_BUG_OR_ZERO to unsigned long.

Since both BUILD_BUG_ON_ZERO() and __is_constexpr() only uses sizeof() on the arguments passed to them, neither of them evaluate the expression unless it is a VLA. Therefore, GENMASK(1, x++) still behaves as expected.

Quoted 5 lines

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since neither BUILD_BUG_OR_ZERO() or __is_constexpr() are asm compatible, disable the checks if the file is included in an asm file.

Quoted 6 lines

Who is going to fix the fallout ? For example, arm64:defconfig no longer compiles with this patch applied.

It seems to me that the benefit of catching misuses of GENMASK is much less than the fallout from no longer compiling kernels, since those kernels won't get any test coverage at all anymore.

We cannot apply this until we fix all errors.

Quoted 8 lines
Quoted 2 lines

I do not understand why Andrew picked up this so soon.

The same was done with the fallthrough warning in mainline, which still results in all "sh" builds failing there (and in -next, obviously). I don't understand the logic either, but maybe it is the new normal.

Guenter

Sorry about that. As Masahiro said, the patch was picked up too soon, I've asked Andrew and Stephen Rothwell to remove the patch in a separate email thread.

FWIW, there seems to be a patch for the build failure already (all arm builds seems to have the same build error):

https://lore.kernel.org/lkml/[email protected]/T/#u

Rikard

#64 lore raw

Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs

In reply to Joe Perches
Quoted 14 lines · Joe Perches
Quoted 9 lines · Rikard Falkeborn
Quoted 4 lines · Masahiro Yamada

How about this?

#define GENMASK_INPUT_CHECK(high, low) \
       BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
              __builtin_constant_p((low) > (high)), (low) > (high), 0))

Thanks for the feedback, your version looks much cleaner than mine. I *think* I had a reason for using __is_constexpr() instead of __builtin_constant_p but I'll try a full rebuild to see if something comes up.

Perhaps a statement expression so high and low aren't possibly evaluated multiple times?

Quoted 10 lines

#define GENMASK_INPUT_CHECK(high, low) \

({								\
	typeof(high) _high = high;				\
	typeof(low) _low = low;					\
	BUILD_BUG_ON_ZERO(__builtin_constant_p(_low > _high,	\
					       _low > _high,	\
					       0))		\
})

That doesn't work I think (even after adding __builtin_choose_expr). Even so, high and low are not evaluated multiple times (they're not evaluated at all in GENMASK_INPUT_CHECK, if they were, the arguments would be evaluated twice since they're evaluated in __GENMASK as well.

__builtin_constant_p does not seem to evaluate it's expression (even though I didn't manage to find that spelled out in the docs, but since __builtin_constant_p is evaluated at compile time it makes sense that it doesn't), and __builtin_choose_expr does not evaluate the operand that is not chosen (this is actually in the docs). Even if it was, BUIlD_BUG_ON_ZERO uses sizeof its argument, which is evaluated at compile time (unless the argument is a VLA).

So this should be safe.

author maintainer
#75 lore raw

Re: [PATCH v2 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs

In reply to Masahiro Yamada
Quoted 1 line · Masahiro Yamada

On Wed, Aug 7, 2019 at 11:27 PM Guenter Roeck <[email protected]> wrote:

[]

Quoted 9 lines
Quoted 6 lines

Who is going to fix the fallout ? For example, arm64:defconfig no longer compiles with this patch applied.

It seems to me that the benefit of catching misuses of GENMASK is much less than the fallout from no longer compiling kernels, since those kernels won't get any test coverage at all anymore.

We cannot apply this until we fix all errors. I do not understand why Andrew picked up this so soon.

I think it makes complete sense to break -next (not mainline) and force
people to fix defects. Especially these types of defects that are
trivial to fix.

I already sent patches a month ago for all decimal only defective uses of GENMASK

https://lore.kernel.org/lkml/[email protected]/

A couple of which have _still_ not been picked up.

These have been applied in -next:

     1	9e037bdf743cc081858423ad4123824e846b2358 media: staging: media: cedrus: Fix misuse of GENMASK macro
     2	5ff29d836d1beb347080bd96e6321c811a8e3f62 rtw88: Fix misuse of GENMASK macro
     3	665e985c2f41bebc3e6cee7e04c36a44afbc58f7 mmc: meson-mx-sdio: Fix misuse of GENMASK macro
     4	f7408a3d5b5fd10571a653d1a81ce9167c62727f ASoC: wcd9335: Fix misuse of GENMASK macro
     5	ae8cc91a7d85e018c0c267f580820b2bb558cd48 iio: adc: max9611: Fix misuse of GENMASK macro
     6	aa4c0c9091b0bb4cb261bbe0718d17c2834c4690 net: stmmac: Fix misuses of GENMASK macro
     7	937a944090cca2f19458fd037a8aff61c546f0cd net: ethernet: mediatek: Fix misuses of GENMASK macro
     8	9bdd7bb3a8447fe841cd37ddd9e0a6974b06a0bb clocksource/drivers/npcm: Fix misuse of GENMASK macro
     9	20faba848752901de23a4d45a1174d64d2069dde irqchip/gic-v3-its: Fix misuse of GENMASK macro

These have not:
(and that's a rather sad indictment of lk process defects)

[PATCH 03/12] drm: aspeed_gfx: Fix misuse of GENMASK macro
https://lore.kernel.org/lkml/cddd7ad7e9f81dec1e86c106f04229d21fc21920.1562734889.git.joe@perches.com/

[PATCH 10/12] phy: amlogic: G12A: Fix misuse of GENMASK macro
https://lore.kernel.org/lkml/d149d2851f9aa2425c927cb8e311e20c4b83e186.1562734889.git.joe@perches.com/

At least these last two do not seem to have actual uses.

#76 lore raw

Re: [PATCH v2 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 10 lines · Joe Perches
Quoted 1 line · Masahiro Yamada

On Wed, Aug 7, 2019 at 11:27 PM Guenter Roeck <[email protected]> wrote:

[]

Quoted 7 lines
Quoted 6 lines

Who is going to fix the fallout ? For example, arm64:defconfig no longer compiles with this patch applied.

It seems to me that the benefit of catching misuses of GENMASK is much less than the fallout from no longer compiling kernels, since those kernels won't get any test coverage at all anymore.

Quoted 9 lines
Quoted 2 lines

We cannot apply this until we fix all errors. I do not understand why Andrew picked up this so soon.

I think it makes complete sense to break -next (not mainline) and force
people to fix defects. Especially these types of defects that are
trivial to fix.

I don't think this (from next-20190807):

Build results:

	total: 158 pass: 137 fail: 21
Qemu test results:
	total: 391 pass: 318 fail: 73

is very useful. The situation is bad enough for newly introduced problems. It is all but impossible to get fixes for all problems discovered (or introduced) by adding checks like this one. In some cases, no one will care. In others, no one will pick up patches. Sometimes people won't know or realize that they are expected to fix something. Making the situation worse, the failures introduced by the new checks will hide other accumulating problems.

arch/sh has failed to build in mainline since 7/27 and in -next since next-20190711, due to the added "fallthrough" warning. I don't think that is too useful either. Ok, that situation may be a sign that the architecture isn't maintained as well as it should, but I don't think that this warrants breaking it on purpose in the hope to trigger some kind of reaction.

I don't mind if new checks are introduced, and I agree that it is useful and makes sense. But the checks should only be introduced after a reasonable attempt was made to fix _all_ associated problems. That doesn't mean that the entire work has to be done by the person introducing the check, but I do see that person responsible for making sure (or a reasonable definition of "make sure") that all problems are fixed before actually introducing the check. Yes, I understand, this is a lot of work, but adding checks and letting all hell break loose can not be the answer.

Guenter

author maintainer
#77 lore raw

Re: [PATCH v2 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 40 lines · Guenter Roeck
Quoted 10 lines · Joe Perches
Quoted 1 line · Masahiro Yamada

On Wed, Aug 7, 2019 at 11:27 PM Guenter Roeck <[email protected]> wrote:

[]

Quoted 7 lines
Quoted 6 lines

Who is going to fix the fallout ? For example, arm64:defconfig no longer compiles with this patch applied.

It seems to me that the benefit of catching misuses of GENMASK is much less than the fallout from no longer compiling kernels, since those kernels won't get any test coverage at all anymore.

Quoted 7 lines
Quoted 2 lines

We cannot apply this until we fix all errors. I do not understand why Andrew picked up this so soon.

I think it makes complete sense to break -next (not mainline) and force people to fix defects. Especially these types of defects that are trivial to fix.

I don't think this (from next-20190807):

Build results:

	total: 158 pass: 137 fail: 21
Qemu test results:
	total: 391 pass: 318 fail: 73

is very useful. The situation is bad enough for newly introduced problems. It is all but impossible to get fixes for all problems discovered (or introduced) by adding checks like this one. In some cases, no one will care. In others, no one will pick up patches. Sometimes people won't know or realize that they are expected to fix something. Making the situation worse, the failures introduced by the new checks will hide other accumulating problems.

arch/sh has failed to build in mainline since 7/27 and in -next since next-20190711, due to the added "fallthrough" warning. I don't think that is too useful either. Ok, that situation may be a sign that the architecture isn't maintained as well as it should, but I don't think that this warrants breaking it on purpose in the hope to trigger some kind of reaction.

Quoted 8 lines

I don't mind if new checks are introduced, and I agree that it is useful and makes sense. But the checks should only be introduced after a reasonable attempt was made to fix _all_ associated problems. That doesn't mean that the entire work has to be done by the person introducing the check, but I do see that person responsible for making sure (or a reasonable definition of "make sure") that all problems are fixed before actually introducing the check. Yes, I understand, this is a lot of work, but adding checks and letting all hell break loose can not be the answer.

No hell is unleashed.

It's -next, an integration build, not mainline.

#78 lore raw

Re: [PATCH v2 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 50 lines · Joe Perches
Quoted 40 lines · Guenter Roeck
Quoted 10 lines · Joe Perches
Quoted 1 line · Masahiro Yamada

On Wed, Aug 7, 2019 at 11:27 PM Guenter Roeck <[email protected]> wrote:

[]

Quoted 7 lines
Quoted 6 lines

Who is going to fix the fallout ? For example, arm64:defconfig no longer compiles with this patch applied.

It seems to me that the benefit of catching misuses of GENMASK is much less than the fallout from no longer compiling kernels, since those kernels won't get any test coverage at all anymore.

Quoted 7 lines
Quoted 2 lines

We cannot apply this until we fix all errors. I do not understand why Andrew picked up this so soon.

I think it makes complete sense to break -next (not mainline) and force people to fix defects. Especially these types of defects that are trivial to fix.

I don't think this (from next-20190807):

Build results:

	total: 158 pass: 137 fail: 21
Qemu test results:
	total: 391 pass: 318 fail: 73

is very useful. The situation is bad enough for newly introduced problems. It is all but impossible to get fixes for all problems discovered (or introduced) by adding checks like this one. In some cases, no one will care. In others, no one will pick up patches. Sometimes people won't know or realize that they are expected to fix something. Making the situation worse, the failures introduced by the new checks will hide other accumulating problems.

arch/sh has failed to build in mainline since 7/27 and in -next since next-20190711, due to the added "fallthrough" warning. I don't think that is too useful either. Ok, that situation may be a sign that the architecture isn't maintained as well as it should, but I don't think that this warrants breaking it on purpose in the hope to trigger some kind of reaction.

Quoted 8 lines

I don't mind if new checks are introduced, and I agree that it is useful and makes sense. But the checks should only be introduced after a reasonable attempt was made to fix _all_ associated problems. That doesn't mean that the entire work has to be done by the person introducing the check, but I do see that person responsible for making sure (or a reasonable definition of "make sure") that all problems are fixed before actually introducing the check. Yes, I understand, this is a lot of work, but adding checks and letting all hell break loose can not be the answer.

Quoted 4 lines

No hell is unleashed.

It's -next, an integration build, not mainline.

... and the breakages introduced in -next are making it into mainline without being fixed, as I just pointed out above. That by itself is bad. It is much worse if the breakage is introduced on purpose.

The criteria for -next _used_ to be "ready for mainline". If breaking -next on purpose is the new normal, no one should be surprised if it will be tested even less than it is today.

Guenter

#79 lore raw

Re: [PATCH v2 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs

In reply to Rikard Falkeborn
Thank you for the patch! Perhaps something to improve:

Hi Rikard,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[cannot apply to v5.3-rc3 next-20190807]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url: https://github.com/0day-ci/linux/commits/Rikard-Falkeborn/linux-bits-h-Clarify-macro-argument-names/20190805-024030
config: i386-defconfig (attached as .config)
compiler: gcc-7 (Debian 7.4.0-10) 7.4.0 reproduce:

        # save the attached .config to linux build tree
        make ARCH=i386 

If you fix the issue, kindly add following tag

All warnings (new ones prefixed by >>):

In file included from include/linux/bits.h:22:0,

                    from arch/x86/include/asm/msr-index.h:5,
                    from arch/x86/boot/cpucheck.c:28:
>> include/linux/build_bug.h:49:0: warning: "BUILD_BUG_ON" redefined
    #define BUILD_BUG_ON(condition) \

In file included from arch/x86/boot/cpucheck.c:22:0:
arch/x86/boot/boot.h:31:0: note: this is the location of the previous definition

    #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))

vim +/BUILD_BUG_ON +49 include/linux/build_bug.h

bc6245e5efd70c Ian Abbott 2017-07-10  40  
bc6245e5efd70c Ian Abbott 2017-07-10  41  /**
bc6245e5efd70c Ian Abbott 2017-07-10  42   * BUILD_BUG_ON - break compile if a condition is true.
bc6245e5efd70c Ian Abbott 2017-07-10  43   * @condition: the condition which the compiler should know is false.
bc6245e5efd70c Ian Abbott 2017-07-10  44   *
bc6245e5efd70c Ian Abbott 2017-07-10  45   * If you have some code which relies on certain constants being equal, or
bc6245e5efd70c Ian Abbott 2017-07-10  46   * some other compile-time-evaluated condition, you should use BUILD_BUG_ON to
bc6245e5efd70c Ian Abbott 2017-07-10  47   * detect if someone changes it.
bc6245e5efd70c Ian Abbott 2017-07-10  48   */

bc6245e5efd70c Ian Abbott 2017-07-10 @49 #define BUILD_BUG_ON(condition) \
bc6245e5efd70c Ian Abbott 2017-07-10 50 BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
bc6245e5efd70c Ian Abbott 2017-07-10 51

:::::: The code at line 49 was first introduced by commit
:::::: bc6245e5efd70c41eaf9334b1b5e646745cb0fb3 bug: split BUILD_BUG stuff out into <linux/build_bug.h>

:::::: TO: Ian Abbott <[email protected]>
:::::: CC: Linus Torvalds <[email protected]>

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation

#80 lore raw

Re: [PATCH v2 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs

In reply to Rikard Falkeborn
Thank you for the patch! Perhaps something to improve:

Hi Rikard,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[cannot apply to v5.3-rc3 next-20190807]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url: https://github.com/0day-ci/linux/commits/Rikard-Falkeborn/linux-bits-h-Clarify-macro-argument-names/20190805-024030
config: x86_64-randconfig-h003-201931 (attached as .config)
compiler: gcc-7 (Debian 7.4.0-10) 7.4.0
reproduce:

        # save the attached .config to linux build tree
        make ARCH=x86_64 

If you fix the issue, kindly add following tag

All warnings (new ones prefixed by >>):

In file included from include/linux/bits.h:22:0,

                    from include/linux/bitops.h:5,
                    from include/linux/kernel.h:12,
                    from include/linux/delay.h:22,
                    from drivers/iio/adc/max9611.c:20:
   drivers/iio/adc/max9611.c: In function 'max9611_init':
   include/linux/build_bug.h:16:45: error: negative width in bit-field '<anonymous>'
    #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
                                                ^
>> include/linux/bits.h:24:18: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
     ((unsigned long)BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
                     ^~~~~~~~~~~~~~~~~
>> include/linux/bits.h:39:3: note: in expansion of macro 'GENMASK_INPUT_CHECK'
     (GENMASK_INPUT_CHECK(high, low) + __GENMASK(high, low))
      ^~~~~~~~~~~~~~~~~~~
>> drivers/iio/adc/max9611.c:86:28: note: in expansion of macro 'GENMASK'
    #define MAX9611_TEMP_MASK  GENMASK(7, 15)
                               ^~~~~~~
>> drivers/iio/adc/max9611.c:483:17: note: in expansion of macro 'MAX9611_TEMP_MASK'
     regval = ret & MAX9611_TEMP_MASK;
                    ^~~~~~~~~~~~~~~~~
--
   In file included from include/linux/bits.h:22:0,
                    from include/linux/bitops.h:5,
                    from include/linux/kernel.h:12,
                    from include/linux/delay.h:22,
                    from drivers/iio//adc/max9611.c:20:
   drivers/iio//adc/max9611.c: In function 'max9611_init':
   include/linux/build_bug.h:16:45: error: negative width in bit-field '<anonymous>'
    #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
                                                ^
>> include/linux/bits.h:24:18: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
     ((unsigned long)BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
                     ^~~~~~~~~~~~~~~~~
>> include/linux/bits.h:39:3: note: in expansion of macro 'GENMASK_INPUT_CHECK'
     (GENMASK_INPUT_CHECK(high, low) + __GENMASK(high, low))
      ^~~~~~~~~~~~~~~~~~~
   drivers/iio//adc/max9611.c:86:28: note: in expansion of macro 'GENMASK'
    #define MAX9611_TEMP_MASK  GENMASK(7, 15)
                               ^~~~~~~
   drivers/iio//adc/max9611.c:483:17: note: in expansion of macro 'MAX9611_TEMP_MASK'
     regval = ret & MAX9611_TEMP_MASK;
                    ^~~~~~~~~~~~~~~~~

vim +/BUILD_BUG_ON_ZERO +24 include/linux/bits.h

    15	
    16	/*
    17	 * Create a contiguous bitmask starting at bit position @low and ending at
    18	 * position @high. For example
    19	 * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
    20	 */
    21	#ifndef __ASSEMBLY__
  > 22	#include <linux/build_bug.h>
    23	#define GENMASK_INPUT_CHECK(high, low) \
  > 24		((unsigned long)BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
    25			__is_constexpr(high) && __is_constexpr(low), \
    26			(low) > (high), UL(0))))
    27	#else
    28	/*
    29	 * BUILD_BUG_ON_ZERO and __is_constexpr() are not available in h files
    30	 * included from asm files, disable the input check if that is the case.
    31	 */
    32	#define GENMASK_INPUT_CHECK(high, low) UL(0)
    33	#endif
    34	
    35	#define __GENMASK(high, low) \
    36		(((~UL(0)) - (UL(1) << (low)) + 1) & \
    37		 (~UL(0) >> (BITS_PER_LONG - 1 - (high))))
    38	#define GENMASK(high, low) \
  > 39		(GENMASK_INPUT_CHECK(high, low) + __GENMASK(high, low))
    40	

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation

#81 lore raw

Re: [PATCH v2 1/2] linux/bits.h: Clarify macro argument names

In reply to Rikard Falkeborn
Quoted 4 lines · Rikard Falkeborn

Be a little more verbose to improve readability.

BTW, I do not understand what the improvement is.
I tend to regard this as a noise commit.

Quoted 39 lines

---
Changes in v2:
- This patch is new in v2

 include/linux/bits.h | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
include/linux/bits.h +8 -9
index 669d69441a62..d4466aa42a9c 100644
@@ -14,16 +14,16 @@
 #define BITS_PER_BYTE          8
 
 /*
- * Create a contiguous bitmask starting at bit position @l and ending at
- * position @h. For example
+ * Create a contiguous bitmask starting at bit position @low and ending at
+ * position @high. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(h, l) \
-       (((~UL(0)) - (UL(1) << (l)) + 1) & \
-        (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+#define GENMASK(high, low) \
+       (((~UL(0)) - (UL(1) << (low)) + 1) & \
+        (~UL(0) >> (BITS_PER_LONG - 1 - (high))))
 
-#define GENMASK_ULL(h, l) \
-       (((~ULL(0)) - (ULL(1) << (l)) + 1) & \
-        (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+#define GENMASK_ULL(high, low) \
+       (((~ULL(0)) - (ULL(1) << (low)) + 1) & \
+        (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (high))))
 
 #endif /* __LINUX_BITS_H */
--

2.22.0

Signature · 2 lines
Best Regards
Masahiro Yamada
#82 lore raw

Re: [PATCH v2 1/2] linux/bits.h: Clarify macro argument names

Quoted 9 lines · Masahiro Yamada
Quoted 4 lines · Rikard Falkeborn

Be a little more verbose to improve readability.

BTW, I do not understand what the improvement is.
I tend to regard this as a noise commit.

Fair enough, I'll drop it and keep l and h as argument names.

author maintainer
#83 lore raw

Re: [PATCH v2 1/2] linux/bits.h: Clarify macro argument names

In reply to Masahiro Yamada
Quoted 8 lines · Masahiro Yamada
Quoted 3 lines · Rikard Falkeborn

Be a little more verbose to improve readability.

BTW, I do not understand what the improvement is.
I tend to regard this as a noise commit.

Non verbose naming clarity is good.

Perhaps adding kernel-doc is good too.

Quoted 42 lines
Quoted 40 lines

---
Changes in v2:
- This patch is new in v2

 include/linux/bits.h | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
include/linux/bits.h +8 -9
index 669d69441a62..d4466aa42a9c 100644
@@ -14,16 +14,16 @@
 #define BITS_PER_BYTE          8
 
 /*
- * Create a contiguous bitmask starting at bit position @l and ending at
- * position @h. For example
+ * Create a contiguous bitmask starting at bit position @low and ending at
+ * position @high. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(h, l) \
-       (((~UL(0)) - (UL(1) << (l)) + 1) & \
-        (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+#define GENMASK(high, low) \
+       (((~UL(0)) - (UL(1) << (low)) + 1) & \
+        (~UL(0) >> (BITS_PER_LONG - 1 - (high))))
 
-#define GENMASK_ULL(h, l) \
-       (((~ULL(0)) - (ULL(1) << (l)) + 1) & \
-        (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+#define GENMASK_ULL(high, low) \
+       (((~ULL(0)) - (ULL(1) << (low)) + 1) & \
+        (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (high))))
 
 #endif /* __LINUX_BITS_H */
--

2.22.0

#84 lore raw

v3 cover Add compile time sanity check of GENMASK inputs

In reply to Rikard Falkeborn

Hello,

A new attempt to try to add build time validity checks of GENMASK (and GENMASK_ULL) inputs. There main differences from v2:

Remove a define of BUILD_BUG_ON in x86/boot to avoid a compiler warning about redefining BUILD_BUG_ON. Instead, use the common one from include/.

Drop patch 2 in v2 where GENMASK arguments where made more verbose.

Add a cast in the BUILD_BUG_ON_ZERO macro change the type to int to avoid the somewhat clumpsy casts of BUILD_BUG_ON_ZERO. The second patch in this series adds such a cast to BUILD_BUG_ON_ZERO, which makes it possible to avoid casts when using BUILD_BUG_ON_ZERO in patch 3.

I have checked all users of BUILD_BUG_ON_ZERO and I did not find a case where adding a cast to int would affect existing users but I'd feel much more comfortable if someone else double (or tripple) checked (there are ~80 instances plus ~10 copies in tools). Perhaps I should have CC:d maintainers of files using BUILD_BUG_ON_ZERO?

Finally, use __builtin_constant_p instead of __is_constexpr. This avoids pulling in kernel.h in bits.h.

Joe Perches sent a patch series to fix existing misuses, currently there are five such misuses (which patches pending) left in Linus tree and two (with patches pending) in linux-next. Those patches should fix all "simple" misuses of GENMASK (cases where the arguments are numerical constants). Pushing v2 to linux-next also revealed an arm-specific misuse where GENMASK was used in another macro (and also broke the arm-builds). There is a patch to fix that by Nathan Chancellor (not in linux-next yet). Those patches should be merged before the last patch of this series to avoid breaking builds.

Changelog
Since v2
- Use __builtin_constant_p instead of __is_constexpr to avoid pulling in kernel.h (that include was missing in v2, so the header was no longer builable standalone
- add cast to BUILD_BUG_ON_ZERO to make the type int
- Remove unnecessary casts due to the above
- Drop patch that renamed macro arguments

Since v1
- Add comment about why inputs are not checked when used in asm file
- Use UL(0) instead of 0
- Extract mask creation in a separate macro to improve readability
- Use high and low instead of h and l (part of this was extracted to a separate patch)
- Updated commit message

Rikard Falkeborn (3):
x86/boot: Use common BUILD_BUG_ON linux/build_bug.h: Change type to int
linux/bits.h: Add compile time sanity check of GENMASK inputs

 arch/x86/boot/boot.h      |  2 --
 arch/x86/boot/main.c      |  1 +
 include/linux/bits.h      | 21 +++++++++++++++++++--
 include/linux/build_bug.h |  4 ++--
 4 files changed, 22 insertions(+), 6 deletions(-)
Signature · 1 line
2.22.0
#85 lore raw

PATCH v3 1/3 x86/boot: Use common BUILD_BUG_ON

Defining BUILD_BUG_ON causes redefinition warnings when adding includes of include/linux/build_bug.h in files unrelated to x86/boot. For example, adding an include of build_bug.h to include/linux/bits.h shows the following warnings:

CC arch/x86/boot/cpucheck.o
In file included from ./include/linux/bits.h:22,

                   from ./arch/x86/include/asm/msr-index.h:5,
                   from arch/x86/boot/cpucheck.c:28:
  ./include/linux/build_bug.h:49: warning: "BUILD_BUG_ON" redefined
     49 | #define BUILD_BUG_ON(condition) \
        |
  In file included from arch/x86/boot/cpucheck.c:22:
  arch/x86/boot/boot.h:31: note: this is the location of the previous definition
     31 | #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
        |

The macro was added to boot.h in commit 62bd0337d0c4 ("Top header file for new x86 setup code"). At that time, BUILD_BUG_ON was defined in kernel.h. Presumably BUILD_BUG_ON was redefined to avoid pulling in kernel.h. Since then, BUILD_BUG_ON and similar macros have been split to a separate header file.

---
 arch/x86/boot/boot.h | 2 --
 arch/x86/boot/main.c | 1 +
 2 files changed, 1 insertion(+), 2 deletions(-)
arch/x86/boot/boot.h +0 -2
index 19eca14b49a0..ca866f1cca2e 100644
@@ -28,8 +28,6 @@
 #include "cpuflags.h"
 
 /* Useful macros */
-#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
-
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
 
 extern struct setup_header hdr;
arch/x86/boot/main.c +1 -0
index 996df3d586f0..c5e55d2c55d0 100644
@@ -13,6 +13,7 @@
 
 #include "boot.h"
 #include "string.h"
+#include <linux/build_bug.h>
 
 struct boot_params boot_params __attribute__((aligned(16)));
 
Signature · 1 line
2.22.0
#88 lore raw

PATCH v3 2/3 linux/build_bug.h: Change type to int

In reply to Rikard Falkeborn

Having BUILD_BUG_ON_ZERO produce a value of type size_t leads to awkward casts in cases where the result needs to be signed, or of smaller type than size_t. To avoid this, cast the value to int instead and rely on implicit type conversions when a larger or unsigned type is needed.

---
Changes in v3:
- This patch is new in v3

 include/linux/build_bug.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/build_bug.h +2 -2
index 0fe5426f2bdc..e3a0be2c90ad 100644
@@ -9,11 +9,11 @@
 #else /* __CHECKER__ */
 /*
  * Force a compilation error if condition is true, but also produce a
- * result (of value 0 and type size_t), so the expression can be used
+ * result (of value 0 and type int), so the expression can be used
  * e.g. in a structure initializer (or where-ever else comma expressions
  * aren't permitted).
  */
-#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
+#define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
 #endif /* __CHECKER__ */
 
 /* Force a compilation error if a constant expression is not a power of 2 */
Signature · 1 line
2.22.0
#90 lore raw

PATCH v3 3/3 linux/bits.h: Add compile time sanity check of GENMASK inputs

In reply to Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON().

__builtin_constant_p does not evaluate is argument, it only checks if it is a constant or not at compile time, and __builtin_choose_expr does not evaluate the expression that is not chosen. Therefore, GENMASK(x++, 0) does only evaluate x++ once.

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since BUILD_BUG_OR_ZERO() is not asm compatible, disable the checks if the file is included in an asm file.

---
Changes in v3:
- Changed back to shorter macro argument names
- Remove casts and use 0 instead of UL(0) in GENMASK_INPUT_CHECK(), since all results in GENMASK_INPUT_CHECK() are now ints. Update commit message to reflect that.

Changes in v2:
- Add comment about why inputs are not checked when used in asm file
- Use UL(0) instead of 0
- Extract mask creation in a separate macro to improve readability
- Use high and low instead of h and l (part of this was extracted to a separate patch)
- Updated commit message

Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 5 of the patches are not in Linus tree, and 2 are not in linux-next. There is also a patch pending by Nathan Chancellor that also needs to be merged before this patch is merged to avoid build failures.

 include/linux/bits.h | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)
include/linux/bits.h +19 -2
index 669d69441a62..4ba0fb609239 100644
@@ -18,12 +18,29 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(h, l) \
+#ifndef __ASSEMBLY__
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l) \
+	(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+		__builtin_constant_p((l) > (h)), (l) > (h), 0)))
+#else
+/*
+ * BUILD_BUG_ON_ZERO is not available in h files included from asm files,
+ * disable the input check if that is the case.
+ */
+#define GENMASK_INPUT_CHECK(h, l) 0
+#endif
+
+#define __GENMASK(h, l) \
 	(((~UL(0)) - (UL(1) << (l)) + 1) & \
 	 (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+#define GENMASK(h, l) \
+	(GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
 
-#define GENMASK_ULL(h, l) \
+#define __GENMASK_ULL(h, l) \
 	(((~ULL(0)) - (ULL(1) << (l)) + 1) & \
 	 (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+#define GENMASK_ULL(h, l) \
+	(GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))
 
 #endif	/* __LINUX_BITS_H */
Signature · 1 line
2.22.0
Reviewed-by on the v3 series
#96 lore raw

Re: [PATCH v3 0/3] Add compile time sanity check of GENMASK inputs

In reply to Rikard Falkeborn
Quoted 16 lines · Rikard Falkeborn

Hello,

A new attempt to try to add build time validity checks of GENMASK (and GENMASK_ULL) inputs. There main differences from v2:

Remove a define of BUILD_BUG_ON in x86/boot to avoid a compiler warning about redefining BUILD_BUG_ON. Instead, use the common one from include/.

Drop patch 2 in v2 where GENMASK arguments where made more verbose.

Add a cast in the BUILD_BUG_ON_ZERO macro change the type to int to avoid the somewhat clumpsy casts of BUILD_BUG_ON_ZERO. The second patch in this series adds such a cast to BUILD_BUG_ON_ZERO, which makes it possible to avoid casts when using BUILD_BUG_ON_ZERO in patch 3.

Quoted 8 lines

I have checked all users of BUILD_BUG_ON_ZERO and I did not find a case where adding a cast to int would affect existing users but I'd feel much more comfortable if someone else double (or tripple) checked (there are ~80 instances plus ~10 copies in tools). Perhaps I should have CC:d maintainers of files using BUILD_BUG_ON_ZERO?

Finally, use __builtin_constant_p instead of __is_constexpr. This avoids pulling in kernel.h in bits.h.

Cool; I like this. I spent some time convincing myself that the side-effects really aren't double-evaluated, and it looks fine to me. :)

For the series:

-Kees

#86 lore raw

[tip:x86/boot] x86/boot: Use common BUILD_BUG_ON

In reply to Rikard Falkeborn
x86/boot: Use common BUILD_BUG_ON
Commit-ID:  f6fabe25f01cb09db51644780193f5ea6c44e04e
Gitweb:     https://git.kernel.org/tip/f6fabe25f01cb09db51644780193f5ea6c44e04e
Author:     Rikard Falkeborn <[email protected]>
AuthorDate: Sun, 11 Aug 2019 20:49:36 +0200
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 12 Aug 2019 20:13:56 +0200

x86/boot: Use common BUILD_BUG_ON

Defining BUILD_BUG_ON causes redefinition warnings when adding includes of include/linux/build_bug.h in files unrelated to x86/boot. For example, adding an include of build_bug.h to include/linux/bits.h shows the following warnings:

CC arch/x86/boot/cpucheck.o
In file included from ./include/linux/bits.h:22,

                   from ./arch/x86/include/asm/msr-index.h:5,
                   from arch/x86/boot/cpucheck.c:28:
  ./include/linux/build_bug.h:49: warning: "BUILD_BUG_ON" redefined
     49 | #define BUILD_BUG_ON(condition) \
        |
  In file included from arch/x86/boot/cpucheck.c:22:
  arch/x86/boot/boot.h:31: note: this is the location of the previous definition
     31 | #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
        |

The macro was added to boot.h in commit 62bd0337d0c4 ("Top header file for new x86 setup code"). At that time, BUILD_BUG_ON was defined in kernel.h. Presumably BUILD_BUG_ON was redefined to avoid pulling in kernel.h. Since then, BUILD_BUG_ON and similar macros have been split to a separate header file.

---
 arch/x86/boot/boot.h | 2 --
 arch/x86/boot/main.c | 1 +
 2 files changed, 1 insertion(+), 2 deletions(-)
arch/x86/boot/boot.h +0 -2
index 19eca14b49a0..ca866f1cca2e 100644
@@ -28,8 +28,6 @@
 #include "cpuflags.h"
 
 /* Useful macros */
-#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
-
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
 
 extern struct setup_header hdr;
arch/x86/boot/main.c +1 -0
index 996df3d586f0..e3add857c2c9 100644
@@ -10,6 +10,7 @@
 /*
  * Main module for the real-mode kernel code
  */
+#include <linux/build_bug.h>
 
 #include "boot.h"
 #include "string.h"
#87 lore raw

[tip:x86/boot] x86/boot: Use common BUILD_BUG_ON

In reply to Rikard Falkeborn
x86/boot: Use common BUILD_BUG_ON
Commit-ID:  d5a1baddf1585885868cbab55989401fb97118c6
Gitweb:     https://git.kernel.org/tip/d5a1baddf1585885868cbab55989401fb97118c6
Author:     Rikard Falkeborn <[email protected]>
AuthorDate: Sun, 11 Aug 2019 20:49:36 +0200
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Fri, 16 Aug 2019 14:15:50 +0200

x86/boot: Use common BUILD_BUG_ON

Defining BUILD_BUG_ON causes redefinition warnings when adding includes of include/linux/build_bug.h in files unrelated to x86/boot. For example, adding an include of build_bug.h to include/linux/bits.h shows the following warnings:

CC arch/x86/boot/cpucheck.o
In file included from ./include/linux/bits.h:22,

                   from ./arch/x86/include/asm/msr-index.h:5,
                   from arch/x86/boot/cpucheck.c:28:
  ./include/linux/build_bug.h:49: warning: "BUILD_BUG_ON" redefined
     49 | #define BUILD_BUG_ON(condition) \
        |
  In file included from arch/x86/boot/cpucheck.c:22:
  arch/x86/boot/boot.h:31: note: this is the location of the previous definition
     31 | #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
        |

The macro was added to boot.h in commit 62bd0337d0c4 ("Top header file for new x86 setup code"). At that time, BUILD_BUG_ON was defined in kernel.h. Presumably BUILD_BUG_ON was redefined to avoid pulling in kernel.h. Since then, BUILD_BUG_ON and similar macros have been split to a separate header file.

---
 arch/x86/boot/boot.h | 2 --
 arch/x86/boot/main.c | 1 +
 2 files changed, 1 insertion(+), 2 deletions(-)
arch/x86/boot/boot.h +0 -2
index 19eca14b49a0..ca866f1cca2e 100644
@@ -28,8 +28,6 @@
 #include "cpuflags.h"
 
 /* Useful macros */
-#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
-
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
 
 extern struct setup_header hdr;
arch/x86/boot/main.c +1 -0
index 996df3d586f0..e3add857c2c9 100644
@@ -10,6 +10,7 @@
 /*
  * Main module for the real-mode kernel code
  */
+#include <linux/build_bug.h>
 
 #include "boot.h"
 #include "string.h"
#32 lore raw

Re: [PATCH 10/12] phy: amlogic: G12A: Fix misuse of GENMASK macro

In reply to Neil Armstrong
Quoted 8 lines · Neil Armstrong
Quoted 7 lines · Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/phy/amlogic/phy-meson-g12a-usb2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Quoted 16 lines
Quoted 6 lines
drivers/phy/amlogic/phy-meson-g12a-usb2.c +0 -0
index 9065ffc85eb4..cd7eccab2649 100644

drivers/phy/amlogic/phy-meson-g12a-usb2.c line 72

Quoted 8 lines
drivers/phy/amlogic/phy-meson-g12a-usb2.c +1 -1
@@ -66,7 +66,7 @@
 #define PHY_CTRL_R14						0x38
 	#define PHY_CTRL_R14_I_RDP_EN				BIT(0)
 	#define PHY_CTRL_R14_I_RPU_SW1_EN			BIT(1)
-	#define PHY_CTRL_R14_I_RPU_SW2_EN			GENMASK(2, 3)
+	#define PHY_CTRL_R14_I_RPU_SW2_EN			GENMASK(3, 2)
 	#define PHY_CTRL_R14_PG_RSTN				BIT(4)
 	#define PHY_CTRL_R14_I_C2L_DATA_16_8			BIT(5)
 	#define PHY_CTRL_R14_I_C2L_ASSERT_SINGLE_EN_ZERO	BIT(6)

Shouldn't this go to stable trees as well?

-Kishon

author maintainer
#33 lore raw

Re: [PATCH 10/12] phy: amlogic: G12A: Fix misuse of GENMASK macro

Quoted 27 lines · Kishon Vijay Abraham I
Quoted 8 lines · Neil Armstrong
Quoted 7 lines · Joe Perches

Arguments are supposed to be ordered high then low.

---
 drivers/phy/amlogic/phy-meson-g12a-usb2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Quoted 16 lines
Quoted 6 lines
drivers/phy/amlogic/phy-meson-g12a-usb2.c +0 -0
index 9065ffc85eb4..cd7eccab2649 100644

drivers/phy/amlogic/phy-meson-g12a-usb2.c line 72

Quoted 8 lines
drivers/phy/amlogic/phy-meson-g12a-usb2.c +1 -1
@@ -66,7 +66,7 @@
 #define PHY_CTRL_R14						0x38
 	#define PHY_CTRL_R14_I_RDP_EN				BIT(0)
 	#define PHY_CTRL_R14_I_RPU_SW1_EN			BIT(1)
-	#define PHY_CTRL_R14_I_RPU_SW2_EN			GENMASK(2, 3)
+	#define PHY_CTRL_R14_I_RPU_SW2_EN			GENMASK(3, 2)
 	#define PHY_CTRL_R14_PG_RSTN				BIT(4)
 	#define PHY_CTRL_R14_I_C2L_DATA_16_8			BIT(5)
 	#define PHY_CTRL_R14_I_C2L_ASSERT_SINGLE_EN_ZERO	BIT(6)
Quoted 1 line

Shouldn't this go to stable trees as well?

The macro define is unused so it doesn't have to go into stable.

Quoted 1 line

-Kishon

#97 lore raw

Re: [PATCH v3 0/3] Add compile time sanity check of GENMASK inputs

In reply to Rikard Falkeborn
Quoted 25 lines · Rikard Falkeborn

Hello,

A new attempt to try to add build time validity checks of GENMASK (and GENMASK_ULL) inputs. There main differences from v2:

Remove a define of BUILD_BUG_ON in x86/boot to avoid a compiler warning about redefining BUILD_BUG_ON. Instead, use the common one from include/.

Drop patch 2 in v2 where GENMASK arguments where made more verbose.

Add a cast in the BUILD_BUG_ON_ZERO macro change the type to int to avoid the somewhat clumpsy casts of BUILD_BUG_ON_ZERO. The second patch in this series adds such a cast to BUILD_BUG_ON_ZERO, which makes it possible to avoid casts when using BUILD_BUG_ON_ZERO in patch 3.

I have checked all users of BUILD_BUG_ON_ZERO and I did not find a case where adding a cast to int would affect existing users but I'd feel much more comfortable if someone else double (or tripple) checked (there are ~80 instances plus ~10 copies in tools). Perhaps I should have CC:d maintainers of files using BUILD_BUG_ON_ZERO?

Finally, use __builtin_constant_p instead of __is_constexpr. This avoids pulling in kernel.h in bits.h.

Quoted 10 lines

Joe Perches sent a patch series to fix existing misuses, currently there are five such misuses (which patches pending) left in Linus tree and two (with patches pending) in linux-next. Those patches should fix all "simple" misuses of GENMASK (cases where the arguments are numerical constants). Pushing v2 to linux-next also revealed an arm-specific misuse where GENMASK was used in another macro (and also broke the arm-builds). There is a patch to fix that by Nathan Chancellor (not in linux-next yet). Those patches should be merged before the last patch of this series to avoid breaking builds.

Ping.

The current status is that patch 1 has been merged into Linus tree through the x86 tree. The patches mentioned about actually fixing the existing misuses have all been merged except two of Joe Perches patches [0], [1], but those patches fixes misuse in unused macros, and will not affect anyones build.

I have testbuilt the two remaining patches rebased on top of Linus tree and on linux-next for aarch64 and x86 without seeing any problems (when v2 of the series went into linux-next, those were the only archs where any problems were spotted (build warning on x86, build error on aarch64)).

[0] https://lore.kernel.org/lkml/cddd7ad7e9f81dec1e86c106f04229d21fc21920.1562734889.git.joe@perches.com/
[1] https://lore.kernel.org/lkml/d149d2851f9aa2425c927cb8e311e20c4b83e186.1562734889.git.joe@perches.com/

Rikard

Reviewed-by on v3 2/3
#89 lore raw

Re: [PATCH v3 2/3] linux/build_bug.h: Change type to int

In reply to Rikard Falkeborn
Quoted 8 lines · Rikard Falkeborn

Having BUILD_BUG_ON_ZERO produce a value of type size_t leads to awkward casts in cases where the result needs to be signed, or of smaller type than size_t. To avoid this, cast the value to int instead and rely on implicit type conversions when a larger or unsigned type is needed.

Quoted 27 lines

Changes in v3:
- This patch is new in v3

 include/linux/build_bug.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/build_bug.h +2 -3
index 0fe5426f2bdc..e3a0be2c90ad 100644
@@ -9,11 +9,11 @@
 #else /* __CHECKER__ */
 /*
  * Force a compilation error if condition is true, but also produce a
- * result (of value 0 and type size_t), so the expression can be used
+ * result (of value 0 and type int), so the expression can be used
  * e.g. in a structure initializer (or where-ever else comma expressions
  * aren't permitted).
  */
-#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
+#define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
 #endif /* __CHECKER__ */
 
 /* Force a compilation error if a constant expression is not a power of 2 */
--

2.22.0

Signature · 2 lines
Best Regards
Masahiro Yamada
Reviewed-by on v3 3/3
#91 lore raw

Re: [PATCH v3 3/3] linux/bits.h: Add compile time sanity check of GENMASK inputs

In reply to Rikard Falkeborn
Quoted 23 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON().

__builtin_constant_p does not evaluate is argument, it only checks if it is a constant or not at compile time, and __builtin_choose_expr does not evaluate the expression that is not chosen. Therefore, GENMASK(x++, 0) does only evaluate x++ once.

Quoted 6 lines

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since BUILD_BUG_OR_ZERO() is not asm compatible, disable the checks if the file is included in an asm file.

Quoted 63 lines

---
Changes in v3:
- Changed back to shorter macro argument names
- Remove casts and use 0 instead of UL(0) in GENMASK_INPUT_CHECK(), since all results in GENMASK_INPUT_CHECK() are now ints. Update commit message to reflect that.

Changes in v2:
- Add comment about why inputs are not checked when used in asm file
- Use UL(0) instead of 0
- Extract mask creation in a separate macro to improve readability
- Use high and low instead of h and l (part of this was extracted to a separate patch)
- Updated commit message

Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 5 of the patches are not in Linus tree, and 2 are not in linux-next. There is also a patch pending by Nathan Chancellor that also needs to be merged before this patch is merged to avoid build failures.

 include/linux/bits.h | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)
include/linux/bits.h +19 -3
index 669d69441a62..4ba0fb609239 100644
@@ -18,12 +18,29 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(h, l) \
+#ifndef __ASSEMBLY__
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l) \
+       (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+               __builtin_constant_p((l) > (h)), (l) > (h), 0)))
+#else
+/*
+ * BUILD_BUG_ON_ZERO is not available in h files included from asm files,
+ * disable the input check if that is the case.
+ */
+#define GENMASK_INPUT_CHECK(h, l) 0
+#endif
+
+#define __GENMASK(h, l) \
        (((~UL(0)) - (UL(1) << (l)) + 1) & \
         (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+#define GENMASK(h, l) \
+       (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
 
-#define GENMASK_ULL(h, l) \
+#define __GENMASK_ULL(h, l) \
        (((~ULL(0)) - (ULL(1) << (l)) + 1) & \
         (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+#define GENMASK_ULL(h, l) \
+       (GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))
 
 #endif /* __LINUX_BITS_H */
--

2.22.0

Signature · 2 lines
Best Regards
Masahiro Yamada
#92 lore raw

Re: [PATCH v3 3/3] linux/bits.h: Add compile time sanity check of GENMASK inputs

In reply to Rikard Falkeborn

Hi Rikard,

Quoted 78 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON().

__builtin_constant_p does not evaluate is argument, it only checks if it is a constant or not at compile time, and __builtin_choose_expr does not evaluate the expression that is not chosen. Therefore, GENMASK(x++, 0) does only evaluate x++ once.

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since BUILD_BUG_OR_ZERO() is not asm compatible, disable the checks if the file is included in an asm file.

---
Changes in v3:
- Changed back to shorter macro argument names
- Remove casts and use 0 instead of UL(0) in GENMASK_INPUT_CHECK(), since all results in GENMASK_INPUT_CHECK() are now ints. Update commit message to reflect that.

Changes in v2:
- Add comment about why inputs are not checked when used in asm file
- Use UL(0) instead of 0
- Extract mask creation in a separate macro to improve readability
- Use high and low instead of h and l (part of this was extracted to a separate patch)
- Updated commit message

Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 5 of the patches are not in Linus tree, and 2 are not in linux-next. There is also a patch pending by Nathan Chancellor that also needs to be merged before this patch is merged to avoid build failures.

 include/linux/bits.h | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)
include/linux/bits.h +15 -1
index 669d69441a62..4ba0fb609239 100644
@@ -18,12 +18,29 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(h, l) \
+#ifndef __ASSEMBLY__
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l) \
+       (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+               __builtin_constant_p((l) > (h)), (l) > (h), 0)))
+#else
+/*
+ * BUILD_BUG_ON_ZERO is not available in h files included from asm files,
+ * disable the input check if that is the case.
+ */
+#define GENMASK_INPUT_CHECK(h, l) 0
+#endif
+
+#define __GENMASK(h, l) \
        (((~UL(0)) - (UL(1) << (l)) + 1) & \
         (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+#define GENMASK(h, l) \

include/linux/bits.h line 46

Quoted 10 lines
include/linux/bits.h +4 -1
+       (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
 
-#define GENMASK_ULL(h, l) \
+#define __GENMASK_ULL(h, l) \
        (((~ULL(0)) - (ULL(1) << (l)) + 1) & \
         (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+#define GENMASK_ULL(h, l) \
+       (GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))
 
 #endif /* __LINUX_BITS_H */

This is now commit 0fd35cd30a2fece1 ("linux/bits.h: add compile time sanity check of GENMASK inputs") in next-20191008.

<[email protected]> reported the following failure in sun3_defconfig, which I managed to reproduce with gcc-4.6.3:

    lib/842/842_compress.c: In function '__split_add_bits':
    lib/842/842_compress.c:164:25: error: first argument to
'__builtin_choose_expr' not a constant
    lib/842/842_compress.c:164:25: error: bit-field '<anonymous>'

width not an integer constant
scripts/Makefile.build:265: recipe for target
'lib/842/842_compress.o' failed

__split_add_bits() calls GENMASK_ULL() with a non-constant. However __split_add_bits() itself is called with constants only. Apparently gcc fails to inline __split_add_bits(). Adding inline or always_inline doesn't help.

Gr{oetje,eeting}s,

Geert

Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
#93 lore raw

Re: [PATCH v3 3/3] linux/bits.h: Add compile time sanity check of GENMASK inputs

Hi Geert,

Quoted 92 lines · Geert Uytterhoeven

Hi Rikard,

Quoted 87 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON().

__builtin_constant_p does not evaluate is argument, it only checks if it is a constant or not at compile time, and __builtin_choose_expr does not evaluate the expression that is not chosen. Therefore, GENMASK(x++, 0) does only evaluate x++ once.

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since BUILD_BUG_OR_ZERO() is not asm compatible, disable the checks if the file is included in an asm file.

---
Changes in v3:
- Changed back to shorter macro argument names
- Remove casts and use 0 instead of UL(0) in GENMASK_INPUT_CHECK(), since all results in GENMASK_INPUT_CHECK() are now ints. Update commit message to reflect that.

Changes in v2:
- Add comment about why inputs are not checked when used in asm file
- Use UL(0) instead of 0
- Extract mask creation in a separate macro to improve readability
- Use high and low instead of h and l (part of this was extracted to a separate patch)
- Updated commit message

Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 5 of the patches are not in Linus tree, and 2 are not in linux-next. There is also a patch pending by Nathan Chancellor that also needs to be merged before this patch is merged to avoid build failures.

 include/linux/bits.h | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)
include/linux/bits.h +19 -2
index 669d69441a62..4ba0fb609239 100644
@@ -18,12 +18,29 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(h, l) \
+#ifndef __ASSEMBLY__
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l) \
+       (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+               __builtin_constant_p((l) > (h)), (l) > (h), 0)))
+#else
+/*
+ * BUILD_BUG_ON_ZERO is not available in h files included from asm files,
+ * disable the input check if that is the case.
+ */
+#define GENMASK_INPUT_CHECK(h, l) 0
+#endif
+
+#define __GENMASK(h, l) \
        (((~UL(0)) - (UL(1) << (l)) + 1) & \
         (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+#define GENMASK(h, l) \
+       (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
 
-#define GENMASK_ULL(h, l) \
+#define __GENMASK_ULL(h, l) \
        (((~ULL(0)) - (ULL(1) << (l)) + 1) & \
         (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+#define GENMASK_ULL(h, l) \
+       (GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))
 
Quoted 7 lines

include/linux/bits.h line 46

Quoted 1 line
include/linux/bits.h +0 -0
 #endif /* __LINUX_BITS_H */

This is now commit 0fd35cd30a2fece1 ("linux/bits.h: add compile time sanity check of GENMASK inputs") in next-20191008.

<[email protected]> reported the following failure in sun3_defconfig, which I managed to reproduce with gcc-4.6.3:

Oh dear.

I was able to reproduce this for gcc 4.7 or 4.8,
but I did not see any problem for gcc 4.9+

Perhaps, is this due to broken __builtin_choose_expr or __builtin_constant_p for old compilers?

Quoted 24 lines
    lib/842/842_compress.c: In function '__split_add_bits':
    lib/842/842_compress.c:164:25: error: first argument to
'__builtin_choose_expr' not a constant
    lib/842/842_compress.c:164:25: error: bit-field '<anonymous>'

width not an integer constant
scripts/Makefile.build:265: recipe for target
'lib/842/842_compress.o' failed

__split_add_bits() calls GENMASK_ULL() with a non-constant. However __split_add_bits() itself is called with constants only. Apparently gcc fails to inline __split_add_bits(). Adding inline or always_inline doesn't help.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

Signature · 2 lines
Best Regards
Masahiro Yamada
#94 lore raw

Re: [PATCH v3 3/3] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 104 lines · Masahiro Yamada

Hi Geert,

Quoted 92 lines · Geert Uytterhoeven

Hi Rikard,

Quoted 87 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON().

__builtin_constant_p does not evaluate is argument, it only checks if it is a constant or not at compile time, and __builtin_choose_expr does not evaluate the expression that is not chosen. Therefore, GENMASK(x++, 0) does only evaluate x++ once.

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since BUILD_BUG_OR_ZERO() is not asm compatible, disable the checks if the file is included in an asm file.

---
Changes in v3:
- Changed back to shorter macro argument names
- Remove casts and use 0 instead of UL(0) in GENMASK_INPUT_CHECK(), since all results in GENMASK_INPUT_CHECK() are now ints. Update commit message to reflect that.

Changes in v2:
- Add comment about why inputs are not checked when used in asm file
- Use UL(0) instead of 0
- Extract mask creation in a separate macro to improve readability
- Use high and low instead of h and l (part of this was extracted to a separate patch)
- Updated commit message

Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 5 of the patches are not in Linus tree, and 2 are not in linux-next. There is also a patch pending by Nathan Chancellor that also needs to be merged before this patch is merged to avoid build failures.

 include/linux/bits.h | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)
include/linux/bits.h +19 -2
index 669d69441a62..4ba0fb609239 100644
@@ -18,12 +18,29 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(h, l) \
+#ifndef __ASSEMBLY__
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l) \
+       (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+               __builtin_constant_p((l) > (h)), (l) > (h), 0)))
+#else
+/*
+ * BUILD_BUG_ON_ZERO is not available in h files included from asm files,
+ * disable the input check if that is the case.
+ */
+#define GENMASK_INPUT_CHECK(h, l) 0
+#endif
+
+#define __GENMASK(h, l) \
        (((~UL(0)) - (UL(1) << (l)) + 1) & \
         (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+#define GENMASK(h, l) \
+       (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
 
-#define GENMASK_ULL(h, l) \
+#define __GENMASK_ULL(h, l) \
        (((~ULL(0)) - (ULL(1) << (l)) + 1) & \
         (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+#define GENMASK_ULL(h, l) \
+       (GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))
 
Quoted 7 lines

include/linux/bits.h line 46

Quoted 1 line
include/linux/bits.h +0 -0
 #endif /* __LINUX_BITS_H */

This is now commit 0fd35cd30a2fece1 ("linux/bits.h: add compile time sanity check of GENMASK inputs") in next-20191008.

<[email protected]> reported the following failure in sun3_defconfig, which I managed to reproduce with gcc-4.6.3:

Quoted 28 lines

Oh dear.

I was able to reproduce this for gcc 4.7 or 4.8,
but I did not see any problem for gcc 4.9+

Perhaps, is this due to broken __builtin_choose_expr or __builtin_constant_p for old compilers?

Quoted 14 lines
    lib/842/842_compress.c: In function '__split_add_bits':
    lib/842/842_compress.c:164:25: error: first argument to
'__builtin_choose_expr' not a constant
    lib/842/842_compress.c:164:25: error: bit-field '<anonymous>'

width not an integer constant
scripts/Makefile.build:265: recipe for target
'lib/842/842_compress.o' failed

__split_add_bits() calls GENMASK_ULL() with a non-constant. However __split_add_bits() itself is called with constants only. Apparently gcc fails to inline __split_add_bits(). Adding inline or always_inline doesn't help.

If this is broken for GCC < 4.9,
we might be able to workaround it as follows:

include/linux/bits.h +1 -1
index 4ba0fb609239..f00417baf545 100644
@@ -18,7 +18,7 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#ifndef __ASSEMBLY__
+#if !defined(__ASSEMBLY__) && (!defined(CONFIG_CC_IS_GCC) ||

CONFIG_GCC_VERSION >= 49000)
#include <linux/build_bug.h>

 #define GENMASK_INPUT_CHECK(h, l) \
        (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
Signature · 2 lines
Best Regards
Masahiro Yamada
#95 lore raw

Re: [PATCH v3 3/3] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 155 lines · Masahiro Yamada
Quoted 104 lines · Masahiro Yamada

Hi Geert,

Quoted 92 lines · Geert Uytterhoeven

Hi Rikard,

Quoted 87 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON().

__builtin_constant_p does not evaluate is argument, it only checks if it is a constant or not at compile time, and __builtin_choose_expr does not evaluate the expression that is not chosen. Therefore, GENMASK(x++, 0) does only evaluate x++ once.

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since BUILD_BUG_OR_ZERO() is not asm compatible, disable the checks if the file is included in an asm file.

---
Changes in v3:
- Changed back to shorter macro argument names
- Remove casts and use 0 instead of UL(0) in GENMASK_INPUT_CHECK(), since all results in GENMASK_INPUT_CHECK() are now ints. Update commit message to reflect that.

Changes in v2:
- Add comment about why inputs are not checked when used in asm file
- Use UL(0) instead of 0
- Extract mask creation in a separate macro to improve readability
- Use high and low instead of h and l (part of this was extracted to a separate patch)
- Updated commit message

Joe Perches sent a series to fix the existing misuses of GENMASK() that needs to be merged before this to avoid build failures. Currently, 5 of the patches are not in Linus tree, and 2 are not in linux-next. There is also a patch pending by Nathan Chancellor that also needs to be merged before this patch is merged to avoid build failures.

 include/linux/bits.h | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)
include/linux/bits.h +19 -2
index 669d69441a62..4ba0fb609239 100644
@@ -18,12 +18,29 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(h, l) \
+#ifndef __ASSEMBLY__
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l) \
+       (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+               __builtin_constant_p((l) > (h)), (l) > (h), 0)))
+#else
+/*
+ * BUILD_BUG_ON_ZERO is not available in h files included from asm files,
+ * disable the input check if that is the case.
+ */
+#define GENMASK_INPUT_CHECK(h, l) 0
+#endif
+
+#define __GENMASK(h, l) \
        (((~UL(0)) - (UL(1) << (l)) + 1) & \
         (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+#define GENMASK(h, l) \
+       (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
 
-#define GENMASK_ULL(h, l) \
+#define __GENMASK_ULL(h, l) \
        (((~ULL(0)) - (ULL(1) << (l)) + 1) & \
         (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+#define GENMASK_ULL(h, l) \
+       (GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))
 
Quoted 7 lines

include/linux/bits.h line 46

Quoted 1 line
include/linux/bits.h +0 -0
 #endif /* __LINUX_BITS_H */

This is now commit 0fd35cd30a2fece1 ("linux/bits.h: add compile time sanity check of GENMASK inputs") in next-20191008.

<[email protected]> reported the following failure in sun3_defconfig, which I managed to reproduce with gcc-4.6.3:

Quoted 28 lines

Oh dear.

I was able to reproduce this for gcc 4.7 or 4.8,
but I did not see any problem for gcc 4.9+

Perhaps, is this due to broken __builtin_choose_expr or __builtin_constant_p for old compilers?

Quoted 14 lines
    lib/842/842_compress.c: In function '__split_add_bits':
    lib/842/842_compress.c:164:25: error: first argument to
'__builtin_choose_expr' not a constant
    lib/842/842_compress.c:164:25: error: bit-field '<anonymous>'

width not an integer constant
scripts/Makefile.build:265: recipe for target
'lib/842/842_compress.o' failed

__split_add_bits() calls GENMASK_ULL() with a non-constant. However __split_add_bits() itself is called with constants only. Apparently gcc fails to inline __split_add_bits(). Adding inline or always_inline doesn't help.

If this is broken for GCC < 4.9,
we might be able to workaround it as follows:

include/linux/bits.h +1 -1
index 4ba0fb609239..f00417baf545 100644
@@ -18,7 +18,7 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#ifndef __ASSEMBLY__
+#if !defined(__ASSEMBLY__) && (!defined(CONFIG_CC_IS_GCC) ||
 CONFIG_GCC_VERSION >= 49000)
 #include <linux/build_bug.h>
 #define GENMASK_INPUT_CHECK(h, l) \
Quoted 6 lines
        (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
Signature · 2 lines
Best Regards
Masahiro Yamada

Hi Masahiro, Geert,

It seems it is broken for GCC < 4.9, see [1]. I'll try disabling it for too old compilers and resend.

In the meantime, I guess it should be dropped from linux-next?

Rikard

[1]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19449

#98 lore raw

v4 cover Add compile time sanity check of GENMASK inputs

In reply to Rikard Falkeborn

Hello,

Add build time validity checks of GENMASK (and GENMASK_ULL) inputs. The main differences from v3:

- Patch v3 1/3 was merged into Linus tree through the x86 tree and is not part of this series any longer.
- Disable the input check for GCC < 4.9 due to a gcc bug.

Joe Perches sent a patch series to fix existing misuses, currently there are two remaining such misuses (which patches pending) left in Linus tree. However, the remaining two cases are in unused macros and will not break any builds until someone tries to use them. There was also an arm-specific misuse which have also been fixed since v2 of this patchset was merged to linux-next. When v3 of this patchset was included in linux-next, there were not additional build failures or warnings (there are some failed builds due to other patches though), however <[email protected]> and Geert Uytterhoeven reported that it broke compilation with old versions of gcc so a v4 is needed.

Changelog
Since v3
- Patch v2 1/3 (the x86 build warning) has been merged into Linus tree through the x86 tree (and is therefore not part of v4).
- Disable the GENMASK input check if GCC version < 4.9 due to a compiler bug [0].

[0]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19449

Since v2
- Use __builtin_constant_p instead of __is_constexpr to avoid pulling in kernel.h (that include was missing in v2, so the header was no longer builable standalone
- add cast to BUILD_BUG_ON_ZERO to make the type int
- Remove unnecessary casts due to the above
- Drop patch that renamed macro arguments

Since v1
- Add comment about why inputs are not checked when used in asm file
- Use UL(0) instead of 0
- Extract mask creation in a separate macro to improve readability
- Use high and low instead of h and l (part of this was extracted to a separate patch)
- Updated commit message

Rikard Falkeborn (2):
linux/build_bug.h: Change type to int
linux/bits.h: Add compile time sanity check of GENMASK inputs

 include/linux/bits.h      | 22 ++++++++++++++++++++--
 include/linux/build_bug.h |  4 ++--
 2 files changed, 22 insertions(+), 4 deletions(-)
Signature · 1 line
2.23.0
#99 lore raw

PATCH v4 1/2 linux/build_bug.h: Change type to int

Having BUILD_BUG_ON_ZERO produce a value of type size_t leads to awkward casts in cases where the result needs to be signed, or of smaller type than size_t. To avoid this, cast the value to int instead and rely on implicit type conversions when a larger or unsigned type is needed.

---
Changes in v4:
- Added Kees and Masahiros reviewed-by tags.
Changes in v3:
- This patch is new in v3

 include/linux/build_bug.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/build_bug.h +2 -2
index 0fe5426f2bdc..e3a0be2c90ad 100644
@@ -9,11 +9,11 @@
 #else /* __CHECKER__ */
 /*
  * Force a compilation error if condition is true, but also produce a
- * result (of value 0 and type size_t), so the expression can be used
+ * result (of value 0 and type int), so the expression can be used
  * e.g. in a structure initializer (or where-ever else comma expressions
  * aren't permitted).
  */
-#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
+#define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
 #endif /* __CHECKER__ */
 
 /* Force a compilation error if a constant expression is not a power of 2 */
Signature · 1 line
2.23.0
#100 lore raw

PATCH v4 2/2 linux/bits.h: Add compile time sanity check of GENMASK inputs

In reply to Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON().

__builtin_constant_p does not evaluate is argument, it only checks if it is a constant or not at compile time, and __builtin_choose_expr does not evaluate the expression that is not chosen. Therefore, GENMASK(x++, 0) does only evaluate x++ once.

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since BUILD_BUG_OR_ZERO() is not asm compatible, disable the checks if the file is included in an asm file.

Due to bugs in GCC versions before 4.9 [0], disable the check if building with a too old GCC compiler.

[0]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19449

---
Geert, can you check if this works better? I do not have gcc 4.6-4.8 readily installed.

Kees, Masahiro, since I changed this patch, I didn't include your reviewed-by tags.

Changes in v4:
- Disable the argument check for GCC < 4.9 due to a compiler bug.
Changes in v3:
- Changed back to shorter macro argument names
- Remove casts and use 0 instead of UL(0) in GENMASK_INPUT_CHECK(), since all results in GENMASK_INPUT_CHECK() are now ints. Update commit message to reflect that.

Changes in v2:
- Add comment about why inputs are not checked when used in asm file
- Use UL(0) instead of 0
- Extract mask creation in a separate macro to improve readability
- Use high and low instead of h and l (part of this was extracted to a separate patch)
- Updated commit message

Joe Perches sent a series to fix the existing misuses of GENMASK(). Those patches have been merged into Linus tree except two places where the GENMASK misuse is in unused macros, which will not fail to build. There was also a patch by Nathan Chancellor that have now been merged.

 include/linux/bits.h | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)
include/linux/bits.h +20 -2
index 669d69441a62..f108302a3121 100644
@@ -18,12 +18,30 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(h, l) \
+#if !defined(__ASSEMBLY__) && \
+	(!defined(CONFIG_CC_IS_GCC) || CONFIG_GCC_VERSION >= 49000)
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l) \
+	(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+		__builtin_constant_p((l) > (h)), (l) > (h), 0)))
+#else
+/*
+ * BUILD_BUG_ON_ZERO is not available in h files included from asm files,
+ * disable the input check if that is the case.
+ */
+#define GENMASK_INPUT_CHECK(h, l) 0
+#endif
+
+#define __GENMASK(h, l) \
 	(((~UL(0)) - (UL(1) << (l)) + 1) & \
 	 (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+#define GENMASK(h, l) \
+	(GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
 
-#define GENMASK_ULL(h, l) \
+#define __GENMASK_ULL(h, l) \
 	(((~ULL(0)) - (ULL(1) << (l)) + 1) & \
 	 (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+#define GENMASK_ULL(h, l) \
+	(GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))
 
 #endif	/* __LINUX_BITS_H */
Signature · 1 line
2.23.0
Reviewed-by on v4 2/2
#101 lore raw

Re: [Patch v4 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 28 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON().

__builtin_constant_p does not evaluate is argument, it only checks if it is a constant or not at compile time, and __builtin_choose_expr does not evaluate the expression that is not chosen. Therefore, GENMASK(x++, 0) does only evaluate x++ once.

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since BUILD_BUG_OR_ZERO() is not asm compatible, disable the checks if the file is included in an asm file.

Quoted 6 lines

Due to bugs in GCC versions before 4.9 [0], disable the check if building with a too old GCC compiler.

[0]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19449

Quoted 71 lines

---
Geert, can you check if this works better? I do not have gcc 4.6-4.8 readily installed.

Kees, Masahiro, since I changed this patch, I didn't include your reviewed-by tags.

Changes in v4:
- Disable the argument check for GCC < 4.9 due to a compiler bug.
Changes in v3:
- Changed back to shorter macro argument names
- Remove casts and use 0 instead of UL(0) in GENMASK_INPUT_CHECK(), since all results in GENMASK_INPUT_CHECK() are now ints. Update commit message to reflect that.

Changes in v2:
- Add comment about why inputs are not checked when used in asm file
- Use UL(0) instead of 0
- Extract mask creation in a separate macro to improve readability
- Use high and low instead of h and l (part of this was extracted to a separate patch)
- Updated commit message

Joe Perches sent a series to fix the existing misuses of GENMASK(). Those patches have been merged into Linus tree except two places where the GENMASK misuse is in unused macros, which will not fail to build. There was also a patch by Nathan Chancellor that have now been merged.

 include/linux/bits.h | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)
include/linux/bits.h +20 -3
index 669d69441a62..f108302a3121 100644
@@ -18,12 +18,30 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(h, l) \
+#if !defined(__ASSEMBLY__) && \
+       (!defined(CONFIG_CC_IS_GCC) || CONFIG_GCC_VERSION >= 49000)
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l) \
+       (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+               __builtin_constant_p((l) > (h)), (l) > (h), 0)))
+#else
+/*
+ * BUILD_BUG_ON_ZERO is not available in h files included from asm files,
+ * disable the input check if that is the case.
+ */
+#define GENMASK_INPUT_CHECK(h, l) 0
+#endif
+
+#define __GENMASK(h, l) \
        (((~UL(0)) - (UL(1) << (l)) + 1) & \
         (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+#define GENMASK(h, l) \
+       (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
 
-#define GENMASK_ULL(h, l) \
+#define __GENMASK_ULL(h, l) \
        (((~ULL(0)) - (ULL(1) << (l)) + 1) & \
         (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+#define GENMASK_ULL(h, l) \
+       (GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))
 
 #endif /* __LINUX_BITS_H */
--

2.23.0

Signature · 2 lines
Best Regards
Masahiro Yamada
#102 lore raw

Re: [Patch v4 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs

In reply to Rikard Falkeborn
Quoted 27 lines · On Wed, 9 Oct 2019 23:45:02 +0200 Rikard Falkeborn…

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON().

__builtin_constant_p does not evaluate is argument, it only checks if it is a constant or not at compile time, and __builtin_choose_expr does not evaluate the expression that is not chosen. Therefore, GENMASK(x++, 0) does only evaluate x++ once.

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since BUILD_BUG_OR_ZERO() is not asm compatible, disable the checks if the file is included in an asm file.

Quoted 4 lines

Due to bugs in GCC versions before 4.9 [0], disable the check if building with a too old GCC compiler.

[0]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19449

I'm seeing some breakage in code which is newly added in linux-next:

sound/soc/codecs/tas2562.c: In function tas2562_set_dai_tdm_slot:
./include/linux/build_bug.h:16:51: error: negative width in bit-field <anonymous>

 #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
                                                   ^

./include/linux/bits.h:25:3: note: in expansion of macro BUILD_BUG_ON_ZERO
(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
^~~~~~~~~~~~~~~~~
./include/linux/bits.h:39:3: note: in expansion of macro GENMASK_INPUT_CHECK
(GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
^~~~~~~~~~~~~~~~~~~
sound/soc/codecs/tas2562.h:65:37: note: in expansion of macro GENMASK

 #define TAS2562_TDM_CFG2_RXLEN_MASK GENMASK(0, 1)
                                     ^~~~~~~
sound/soc/codecs/tas2562.c:160:11: note: in expansion of macro TAS2562_TDM_CFG2_RXLEN_MASK
           TAS2562_TDM_CFG2_RXLEN_MASK,
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/linux/build_bug.h:16:51: error: negative width in bit-field <anonymous>
 #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
                                                   ^

./include/linux/bits.h:25:3: note: in expansion of macro BUILD_BUG_ON_ZERO
(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \

and

In file included from ./include/linux/bits.h:23:0,

                 from ./include/linux/ioport.h:15,
                 from ./include/linux/acpi.h:12,
                 from drivers/crypto/hisilicon/hpre/hpre_main.c:3:
./include/linux/build_bug.h:16:51: error: negative width in bit-field ‘<anonymous>’
 #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
                                                   ^

./include/linux/bits.h:25:3: note: in expansion of macro ‘BUILD_BUG_ON_ZERO’
(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
^~~~~~~~~~~~~~~~~
./include/linux/bits.h:39:3: note: in expansion of macro ‘GENMASK_INPUT_CHECK’
(GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
^~~~~~~~~~~~~~~~~~~
drivers/crypto/hisilicon/hpre/hpre_main.c:119:15: note: in expansion of macro ‘GENMASK’
{ .int_msk = GENMASK(10, 15), .msg = "hpre_ooo_rdrsp_err" },

               ^~~~~~~
./include/linux/build_bug.h:16:51: error: negative width in bit-field ‘<anonymous>’
 #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
                                                   ^

./include/linux/bits.h:25:3: note: in expansion of macro ‘BUILD_BUG_ON_ZERO’
(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
^~~~~~~~~~~~~~~~~
./include/linux/bits.h:39:3: note: in expansion of macro ‘GENMASK_INPUT_CHECK’
(GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
^~~~~~~~~~~~~~~~~~~
drivers/crypto/hisilicon/hpre/hpre_main.c:120:15: note: in expansion of macro ‘GENMASK’
{ .int_msk = GENMASK(16, 21), .msg = "hpre_ooo_wrrsp_err" },

               ^~~~~~~
#103 lore raw

Re: [Patch v4 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 83 lines · Andrew Morton
Quoted 27 lines · On Wed, 9 Oct 2019 23:45:02 +0200 Rikard Falkeborn…

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON().

__builtin_constant_p does not evaluate is argument, it only checks if it is a constant or not at compile time, and __builtin_choose_expr does not evaluate the expression that is not chosen. Therefore, GENMASK(x++, 0) does only evaluate x++ once.

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since BUILD_BUG_OR_ZERO() is not asm compatible, disable the checks if the file is included in an asm file.

Quoted 4 lines

Due to bugs in GCC versions before 4.9 [0], disable the check if building with a too old GCC compiler.

[0]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19449

I'm seeing some breakage in code which is newly added in linux-next:

sound/soc/codecs/tas2562.c: In function tas2562_set_dai_tdm_slot:
./include/linux/build_bug.h:16:51: error: negative width in bit-field <anonymous>

 #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
                                                   ^
./include/linux/bits.h:25:3: note: in expansion of macro BUILD_BUG_ON_ZERO
  (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
   ^~~~~~~~~~~~~~~~~

./include/linux/bits.h:39:3: note: in expansion of macro GENMASK_INPUT_CHECK
(GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
^~~~~~~~~~~~~~~~~~~
sound/soc/codecs/tas2562.h:65:37: note: in expansion of macro GENMASK

 #define TAS2562_TDM_CFG2_RXLEN_MASK GENMASK(0, 1)
                                     ^~~~~~~
sound/soc/codecs/tas2562.c:160:11: note: in expansion of macro TAS2562_TDM_CFG2_RXLEN_MASK
           TAS2562_TDM_CFG2_RXLEN_MASK,
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/linux/build_bug.h:16:51: error: negative width in bit-field <anonymous>
 #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
                                                   ^

./include/linux/bits.h:25:3: note: in expansion of macro BUILD_BUG_ON_ZERO
(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \

and

In file included from ./include/linux/bits.h:23:0,

                 from ./include/linux/ioport.h:15,
                 from ./include/linux/acpi.h:12,
                 from drivers/crypto/hisilicon/hpre/hpre_main.c:3:
./include/linux/build_bug.h:16:51: error: negative width in bit-field ‘<anonymous>’
 #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
                                                   ^
./include/linux/bits.h:25:3: note: in expansion of macro ‘BUILD_BUG_ON_ZERO’
  (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
   ^~~~~~~~~~~~~~~~~

./include/linux/bits.h:39:3: note: in expansion of macro ‘GENMASK_INPUT_CHECK’
(GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
^~~~~~~~~~~~~~~~~~~
drivers/crypto/hisilicon/hpre/hpre_main.c:119:15: note: in expansion of macro ‘GENMASK’
{ .int_msk = GENMASK(10, 15), .msg = "hpre_ooo_rdrsp_err" },

               ^~~~~~~
./include/linux/build_bug.h:16:51: error: negative width in bit-field ‘<anonymous>’
 #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
                                                   ^
./include/linux/bits.h:25:3: note: in expansion of macro ‘BUILD_BUG_ON_ZERO’
  (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
   ^~~~~~~~~~~~~~~~~
Quoted 7 lines

./include/linux/bits.h:39:3: note: in expansion of macro ‘GENMASK_INPUT_CHECK’
(GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
^~~~~~~~~~~~~~~~~~~
drivers/crypto/hisilicon/hpre/hpre_main.c:120:15: note: in expansion of macro ‘GENMASK’
{ .int_msk = GENMASK(16, 21), .msg = "hpre_ooo_wrrsp_err" },

               ^~~~~~~

As of next-20191021, those breakages are fixed ([0], [1]). next-20191021 now builds (at least for x86-64) with the GENMASK compile checks added.

I also stumbled upon [2], which is a fix for an unused macro in a header in mips/include/asm. next-201008 contained both v3 of this patch and the mips header with the bad GENMASK in without build regressions, so it *should* be ok to include v4 (but given the track record of this patch, I totally understand if you want to wait until [2] lands in mips-next and linux-next).

Rikard

[0]: https://lore.kernel.org/patchwork/patch/1139777/
[1]: https://lore.kernel.org/patchwork/patch/1139778/
[2]: https://lore.kernel.org/linux-mips/[email protected]/T/#u

#104 lore raw

Re: [Patch v4 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 21 lines · Rikard Falkeborn
Quoted 9 lines · Andrew Morton
Quoted 4 lines · On Wed, 9 Oct 2019 23:45:02 +0200 Rikard Falkeborn…

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

I'm seeing some breakage in code which is newly added in linux-next:

As of next-20191021, those breakages are fixed ([0], [1]). next-20191021 now builds (at least for x86-64) with the GENMASK compile checks added.

I also stumbled upon [2], which is a fix for an unused macro in a header in mips/include/asm. next-201008 contained both v3 of this patch and the mips header with the bad GENMASK in without build regressions, so it *should* be ok to include v4 (but given the track record of this patch, I totally understand if you want to wait until [2] lands in mips-next and linux-next).

Quoted 5 lines

Rikard

[0]: https://lore.kernel.org/patchwork/patch/1139777/
[1]: https://lore.kernel.org/patchwork/patch/1139778/
[2]: https://lore.kernel.org/linux-mips/[email protected]/T/#u

And as of next-20191031, the mentioned mips-header is fixed [0]. Also, a recently introduced arm-bug has also been fixed. I just built x86-64 and arm64 allmodconfigs without issue.

Trying to get this patch merged feels a bit like playing whack a-mole. Perhaps it would have been better to make it a warning at first, and then promote the warning to an error in a later release? Then everyone would have the warning in their tree when they do development and the number if issues in next would be (almost) zero.

Rikard

[0]: https://lore.kernel.org/linux-mips/20191009013721.qda2bo5teppr7nom@pburton-laptop/T/#m6e7cd9c89ef06240fe3cd36a60bd73eff1a1ea5d
[1]: https://www.spinics.net/lists/arm-kernel/msg764473.html

#105 lore raw

PATCH v5 1/1 linux/bits.h: Add compile time sanity check of GENMASK inputs

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON().

__builtin_constant_p does not evaluate is argument, it only checks if it is a constant or not at compile time, and __builtin_choose_expr does not evaluate the expression that is not chosen. Therefore, GENMASK(x++, 0) does only evaluate x++ once.

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since BUILD_BUG_OR_ZERO() is not asm compatible, disable the checks if the file is included in an asm file.

Due to bugs in GCC versions before 4.9 [0], disable the check if building with a too old GCC compiler.

[0]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19449

---
Another attempt to get this merged. I've test built allmodconfig for i386, x86_64 and arm64 for linux-next 20200306 without issues. Also, the last known GENMASK issue was just merged into Linus tree [1].

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=96b4ea324ae92386db2b0c73ace597c80cde1ecb

Changes in v5:
- Added Masahiros Reviewed-by
- Waited for bugfixes to get merged

Changes in v4:
- Disable the argument check for GCC < 4.9 due to a compiler bug.

Changes in v3:
- Changed back to shorter macro argument names
- Remove casts and use 0 instead of UL(0) in GENMASK_INPUT_CHECK(), since all results in GENMASK_INPUT_CHECK() are now ints. Update commit message to reflect that.

Changes in v2:
- Add comment about why inputs are not checked when used in asm file
- Use UL(0) instead of 0
- Extract mask creation in a separate macro to improve readability
- Use high and low instead of h and l (part of this was extracted to a separate patch)
- Updated commit message

Joe Perches sent a series to fix the existing misuses of GENMASK(). Those patches have been merged into Linus tree except two places where the GENMASK misuse is in unused macros, which will not fail to build. There was also a patch by Nathan Chancellor that have now been merged.

 include/linux/bits.h | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)
include/linux/bits.h +20 -2
index 669d69441a62..f108302a3121 100644
@@ -18,12 +18,30 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(h, l) \
+#if !defined(__ASSEMBLY__) && \
+	(!defined(CONFIG_CC_IS_GCC) || CONFIG_GCC_VERSION >= 49000)
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l) \
+	(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+		__builtin_constant_p((l) > (h)), (l) > (h), 0)))
+#else
+/*
+ * BUILD_BUG_ON_ZERO is not available in h files included from asm files,
+ * disable the input check if that is the case.
+ */
+#define GENMASK_INPUT_CHECK(h, l) 0
+#endif
+
+#define __GENMASK(h, l) \
 	(((~UL(0)) - (UL(1) << (l)) + 1) & \
 	 (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+#define GENMASK(h, l) \
+	(GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
 
-#define GENMASK_ULL(h, l) \
+#define __GENMASK_ULL(h, l) \
 	(((~ULL(0)) - (ULL(1) << (l)) + 1) & \
 	 (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+#define GENMASK_ULL(h, l) \
+	(GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))
 
 #endif	/* __LINUX_BITS_H */
Signature · 1 line
2.25.1
Reviewed-by on v5 1/1
#106 lore raw

Re: [PATCH v5] linux/bits.h: Add compile time sanity check of GENMASK inputs

Quoted 27 lines · Rikard Falkeborn

GENMASK() and GENMASK_ULL() are supposed to be called with the high bit as the first argument and the low bit as the second argument. Mixing them will return a mask with zero bits set.

Recent commits show getting this wrong is not uncommon, see e.g. commit aa4c0c9091b0 ("net: stmmac: Fix misuses of GENMASK macro") and commit 9bdd7bb3a844 ("clocksource/drivers/npcm: Fix misuse of GENMASK macro").

To prevent such mistakes from appearing again, add compile time sanity checking to the arguments of GENMASK() and GENMASK_ULL(). If both arguments are known at compile time, and the low bit is higher than the high bit, break the build to detect the mistake immediately.

Since GENMASK() is used in declarations, BUILD_BUG_ON_ZERO() must be used instead of BUILD_BUG_ON().

__builtin_constant_p does not evaluate is argument, it only checks if it is a constant or not at compile time, and __builtin_choose_expr does not evaluate the expression that is not chosen. Therefore, GENMASK(x++, 0) does only evaluate x++ once.

Commit 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") made the macros in linux/bits.h available in assembly. Since BUILD_BUG_OR_ZERO() is not asm compatible, disable the checks if the file is included in an asm file.

Quoted 6 lines

Due to bugs in GCC versions before 4.9 [0], disable the check if building with a too old GCC compiler.

[0]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19449

-Kees

Quoted 77 lines

---
Another attempt to get this merged. I've test built allmodconfig for i386, x86_64 and arm64 for linux-next 20200306 without issues. Also, the last known GENMASK issue was just merged into Linus tree [1].

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=96b4ea324ae92386db2b0c73ace597c80cde1ecb

Changes in v5:
- Added Masahiros Reviewed-by
- Waited for bugfixes to get merged

Changes in v4:
- Disable the argument check for GCC < 4.9 due to a compiler bug.

Changes in v3:
- Changed back to shorter macro argument names
- Remove casts and use 0 instead of UL(0) in GENMASK_INPUT_CHECK(), since all results in GENMASK_INPUT_CHECK() are now ints. Update commit message to reflect that.

Changes in v2:
- Add comment about why inputs are not checked when used in asm file
- Use UL(0) instead of 0
- Extract mask creation in a separate macro to improve readability
- Use high and low instead of h and l (part of this was extracted to a separate patch)
- Updated commit message

Joe Perches sent a series to fix the existing misuses of GENMASK(). Those patches have been merged into Linus tree except two places where the GENMASK misuse is in unused macros, which will not fail to build. There was also a patch by Nathan Chancellor that have now been merged.

 include/linux/bits.h | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)
include/linux/bits.h +20 -2
index 669d69441a62..f108302a3121 100644
@@ -18,12 +18,30 @@
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(h, l) \
+#if !defined(__ASSEMBLY__) && \
+	(!defined(CONFIG_CC_IS_GCC) || CONFIG_GCC_VERSION >= 49000)
+#include <linux/build_bug.h>
+#define GENMASK_INPUT_CHECK(h, l) \
+	(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+		__builtin_constant_p((l) > (h)), (l) > (h), 0)))
+#else
+/*
+ * BUILD_BUG_ON_ZERO is not available in h files included from asm files,
+ * disable the input check if that is the case.
+ */
+#define GENMASK_INPUT_CHECK(h, l) 0
+#endif
+
+#define __GENMASK(h, l) \
 	(((~UL(0)) - (UL(1) << (l)) + 1) & \
 	 (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
+#define GENMASK(h, l) \
+	(GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
 
-#define GENMASK_ULL(h, l) \
+#define __GENMASK_ULL(h, l) \
 	(((~ULL(0)) - (ULL(1) << (l)) + 1) & \
 	 (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+#define GENMASK_ULL(h, l) \
+	(GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))
 
 #endif	/* __LINUX_BITS_H */
Signature · 1 line
2.25.1
Signature · 1 line
Kees Cook