treewide: Fix GENMASK misuses
Subsystems (30)
Joe Perches
maintainercover 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
Joe Perches
maintainerPATCH 1/12 checkpatch: Add GENMASK tests
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
@@ -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
Joe Perches
maintainerRe: [PATCH 01/12] checkpatch: Add GENMASK tests
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_ULLshould be used.
Hey Andrew, can you add this please.
Quoted 31 lines
Signed-off-by Joe Perches <[email protected]>--- scripts/checkpatch.pl | 15 +++++++++++++++ 1 file changed, 15 insertions(+)scripts/checkpatch.pl +15
-0@@ -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",
Joe Perches
maintainerPATCH 2/12 clocksource/drivers/npcm: Fix misuse of GENMASK macro
In reply to Joe PerchesArguments 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
@@ -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
tip-bot for Joe Perches
merge bot[tip:timers/urgent] clocksource/drivers/npcm: Fix misuse of GENMASK macro
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
@@ -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
Avi Fishman
maintainerRe: [PATCH 02/12] clocksource/drivers/npcm: Fix misuse of GENMASK macro
In reply to Joe PerchesHi,
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.
Signed-off-by Joe Perches <[email protected]>--- drivers/clocksource/timer-npcm7xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/clocksource/timer-npcm7xx.c +0
-0
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
Joe Perches
maintainerPATCH 3/12 drm: aspeed_gfx: Fix misuse of GENMASK macro
In reply to Joe PerchesArguments 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
@@ -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
Joe Perches
maintainerRe: [PATCH 03/12] drm: aspeed_gfx: Fix misuse of GENMASK macro
Quoted 12 lines · Joe Perches
Arguments are supposed to be ordered high then low.
Signed-off-by Joe Perches <[email protected]>--- drivers/gpu/drm/aspeed/aspeed_gfx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/gpu/drm/aspeed/aspeed_gfx.h +0
-0
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?
Andrew Jeffery
Reviewed-byRe: [PATCH 03/12] drm: aspeed_gfx: Fix misuse of GENMASK macro
Quoted 8 lines · Joe Perches
Quoted 7 lines · Joe Perches
Arguments are supposed to be ordered high then low.
Signed-off-by Joe Perches <[email protected]>--- 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@@ -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
Joe Perches
maintainerRe: [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.
Signed-off-by Joe Perches <[email protected]>--- 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@@ -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)Reviewed-by Andrew Jeffery <[email protected]>
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?
Joel Stanley
maintainerRe: [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.
Signed-off-by Joe Perches <[email protected]>--- 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@@ -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)Reviewed-by Andrew Jeffery <[email protected]>
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.gitBut 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
Joe Perches
maintainerRe: [PATCH 03/12] drm: aspeed_gfx: Fix misuse of GENMASK macro
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.
Signed-off-by Joe Perches <[email protected]>--- 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@@ -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)Reviewed-by Andrew Jeffery <[email protected]>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
Joe Perches
maintainerPATCH 4/12 iio: adc: max9611: Fix misuse of GENMASK macro
In reply to Joe PerchesArguments 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
@@ -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
Re: [PATCH 04/12] iio: adc: max9611: Fix misuse of GENMASK macro
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.
Signed-off-by Joe Perches <[email protected]>
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@@ -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
Joe Perches
maintainerRe: [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.
Signed-off-by Joe Perches <[email protected]>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@@ -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
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.
Signed-off-by Joe Perches <[email protected]>
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@@ -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
Re: [PATCH 04/12] iio: adc: max9611: Fix misuse of GENMASK macro
In reply to Joe PerchesHello,
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.
Signed-off-by Joe Perches <[email protected]>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, ®val);
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@@ -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
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.
Signed-off-by Joe Perches <[email protected]>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, ®val);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.
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
jQuoted 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@@ -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
Joe Perches
maintainerPATCH 5/12 irqchip/gic-v3-its: Fix misuse of GENMASK macro
In reply to Joe PerchesArguments 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
@@ -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
Re: [PATCH 05/12] irqchip/gic-v3-its: Fix misuse of GENMASK macro
Quoted 13 lines · Joe Perches
Arguments are supposed to be ordered high then low.
Signed-off-by Joe Perches <[email protected]>--- drivers/irqchip/irq-gic-v3-its.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/irqchip/irq-gic-v3-its.c +0
-0
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...
tip-bot for Joe Perches
merge bot[tip:irq/urgent] irqchip/gic-v3-its: Fix misuse of GENMASK macro
In reply to Joe Perchesirqchip/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
@@ -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;
Joe Perches
maintainerPATCH 6/12 mmc: meson-mx-sdio: Fix misuse of GENMASK macro
In reply to Joe PerchesArguments 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
@@ -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
Re: [PATCH 06/12] mmc: meson-mx-sdio: Fix misuse of GENMASK macro
Quoted 13 lines · Joe Perches
Arguments are supposed to be ordered high then low.
Signed-off-by Joe Perches <[email protected]>--- drivers/mmc/host/meson-mx-sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/mmc/host/meson-mx-sdio.c +0
-0
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)
Re: [PATCH 06/12] mmc: meson-mx-sdio: Fix misuse of GENMASK macro
In reply to Joe PerchesQuoted 4 lines · Joe Perches
Arguments are supposed to be ordered high then low.
Signed-off-by Joe Perches <[email protected]>
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@@ -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
Joe Perches
maintainerPATCH 7/12 net: ethernet: mediatek: Fix misuses of GENMASK macro
In reply to Joe PerchesArguments 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
@@ -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
@@ -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
Joe Perches
maintainerPATCH 8/12 net: stmmac: Fix misuses of GENMASK macro
In reply to Joe PerchesArguments 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
@@ -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
@@ -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
RE: [PATCH 08/12] net: stmmac: Fix misuses of GENMASK macro
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.
Signed-off-by Joe Perches <[email protected]>
If you submit another version please add:
---
Thanks,
Jose Miguel Abreu
Joe Perches
maintainerPATCH 9/12 rtw88: Fix misuse of GENMASK macro
In reply to Joe PerchesArguments 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
@@ -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
RE: [PATCH 09/12] rtw88: Fix misuse of GENMASK macro
Quoted 23 lines
Subject: [PATCH 09/12] rtw88: Fix misuse of GENMASK macro
Arguments are supposed to be ordered high then low.
Signed-off-by Joe Perches <[email protected]>--- drivers/net/wireless/realtek/rtw88/rtw8822b.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/net/wireless/realtek/rtw88/rtw8822b.c +1
-1@@ -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
Re: [PATCH 09/12] rtw88: Fix misuse of GENMASK macro
In reply to Joe PerchesQuoted 4 lines · Joe Perches
Arguments are supposed to be ordered high then low.
Signed-off-by Joe Perches <[email protected]>Acked-by Yan-Hsuan Chuang <[email protected]>
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
Joe Perches
maintainerPATCH 10/12 phy: amlogic: G12A: Fix misuse of GENMASK macro
In reply to Joe PerchesArguments 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
@@ -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
Re: [PATCH 10/12] phy: amlogic: G12A: Fix misuse of GENMASK macro
Quoted 13 lines · Joe Perches
Arguments are supposed to be ordered high then low.
Signed-off-by Joe Perches <[email protected]>--- 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
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)
Re: [PATCH 10/12] phy: amlogic: G12A: Fix misuse of GENMASK macro
Quoted 8 lines · Neil Armstrong
Quoted 7 lines · Joe Perches
Arguments are supposed to be ordered high then low.
Signed-off-by Joe Perches <[email protected]>--- 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
-0drivers/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 Neil Armstrong <[email protected]>
Shouldn't this go to stable trees as well?
-Kishon
Joe Perches
maintainerRe: [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.
Signed-off-by Joe Perches <[email protected]>--- 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
-0drivers/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 Neil Armstrong <[email protected]>
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
Joe Perches
maintainerPATCH 11/12 staging: media: cedrus: Fix misuse of GENMASK macro
In reply to Joe PerchesArguments 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
@@ -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
Re: [PATCH 11/12] staging: media: cedrus: Fix misuse of GENMASK macro
Hi,
Quoted 3 lines · Joe Perches
Arguments are supposed to be ordered high then low.
Signed-off-by Joe Perches <[email protected]>
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@@ -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
Joe Perches
maintainerRe: [PATCH 11/12] staging: media: cedrus: Fix misuse of GENMASK macro
In reply to Joe PerchesQuoted 12 lines · Joe Perches
Arguments are supposed to be ordered high then low.
Signed-off-by Joe Perches <[email protected]>--- 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
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?
Greg Kroah-Hartman
maintainerRe: [PATCH 11/12] staging: media: cedrus: Fix misuse of GENMASK macro
Quoted 15 lines · Joe Perches
Quoted 14 lines · Joe Perches
Arguments are supposed to be ordered high then low.
Signed-off-by Joe Perches <[email protected]>--- 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@@ -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
Joe Perches
maintainerRe: [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.
Signed-off-by Joe Perches <[email protected]>--- 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@@ -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
@@ -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]>
Greg Kroah-Hartman
maintainerRe: [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.
Signed-off-by Joe Perches <[email protected]>--- 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@@ -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
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 :)
Re: [PATCH 11/12] staging: media: cedrus: Fix misuse of GENMASK macro
In reply to Joe PerchesQuoted 15 lines · Joe Perches
Quoted 14 lines · Joe Perches
Arguments are supposed to be ordered high then low.
Signed-off-by Joe Perches <[email protected]>--- 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@@ -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
Joe Perches
maintainerPATCH 12/12 ASoC: wcd9335: Fix misuse of GENMASK macro
In reply to Joe PerchesArguments 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
@@ -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
Mark Brown
maintainerApplied "ASoC: wcd9335: Fix misuse of GENMASK macro" to the asoc tree
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
f7408a3d5b5fd10571a653d1a81ce9167c62727fMon 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
@@ -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
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
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 testsIMHO 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
Joe Perches
maintainerQuoted 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 testsIMHO 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
_intheory_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. ABUILD_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
Joe Perches
maintainerQuoted 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 testsIMHO 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 theUL()
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.
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 theUL()
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
@@ -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
Joe Perches
maintainerQuoted 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 theUL()
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@@ -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 */
PATCH 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 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
@@ -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
Joe Perches
maintainerRe: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs
Quoted 24 lines · Rikard Falkeborn
GENMASK()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON(), and__is_constexpr()must be used instead of__builtin_constant_p().Commit
95b980d62d52("linux/bits.h: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. Since neitherBUILD_BUG_OR_ZERO()or__is_constexpr()are asm compatible, disable the checks if the file is included in an asm file.Signed-off-by Rikard Falkeborn <[email protected]>
Quoted 8 lines
---
Joe Perches sent a series to fix the existing misuses ofGENMASK()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?
Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs
Quoted 10 lines · Joe Perches
Quoted 3 lines · Rikard Falkeborn
GENMASK()andGENMASK_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:
#defineGENMASK_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_MSGor 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).
Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs
In reply to Joe PerchesQuoted 50 lines · Joe Perches
Quoted 24 lines · Rikard Falkeborn
GENMASK()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON(), and__is_constexpr()must be used instead of__builtin_constant_p().Commit
95b980d62d52("linux/bits.h: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. Since neitherBUILD_BUG_OR_ZERO()or__is_constexpr()are asm compatible, disable the checks if the file is included in an asm file.Signed-off-by Rikard Falkeborn <[email protected]>Quoted 8 lines
---
Joe Perches sent a series to fix the existing misuses ofGENMASK()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) 0A 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:
#defineGENMASK_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_MSGor some other mechanism?
Signature · 2 lines
Best Regards Masahiro Yamada
Joe Perches
maintainerRe: [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()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON(), and__is_constexpr()must be used instead of__builtin_constant_p().Commit
95b980d62d52("linux/bits.h: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. Since neitherBUILD_BUG_OR_ZERO()or__is_constexpr()are asm compatible, disable the checks if the file is included in an asm file.Signed-off-by Rikard Falkeborn <[email protected]>Quoted 8 lines
---
Joe Perches sent a series to fix the existing misuses ofGENMASK()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) 0A 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:
#defineGENMASK_INPUT_CHECK(h, l)UL(0)Why?
Consistency with the uses in what's now called __GENMASK
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()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON(), and__is_constexpr()must be used instead of__builtin_constant_p().Commit
95b980d62d52("linux/bits.h: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. Since neitherBUILD_BUG_OR_ZERO()or__is_constexpr()are asm compatible, disable the checks if the file is included in an asm file.Signed-off-by Rikard Falkeborn <[email protected]>Quoted 8 lines
---
Joe Perches sent a series to fix the existing misuses ofGENMASK()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) 0A 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:
#defineGENMASK_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
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()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON(), and__is_constexpr()must be used instead of__builtin_constant_p().Commit
95b980d62d52("linux/bits.h: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. Since neitherBUILD_BUG_OR_ZERO()or__is_constexpr()are asm compatible, disable the checks if the file is included in an asm file.Signed-off-by Rikard Falkeborn <[email protected]>Quoted 8 lines
---
Joe Perches sent a series to fix the existing misuses ofGENMASK()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) 0A 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:
#defineGENMASK_INPUT_CHECK(h, l)UL(0)Why?
Consistency with the uses in what's now called
__GENMASKInconsistent 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?
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()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON(), and__is_constexpr()must be used instead of__builtin_constant_p().Commit
95b980d62d52("linux/bits.h: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. Since neitherBUILD_BUG_OR_ZERO()or__is_constexpr()are asm compatible, disable the checks if the file is included in an asm file.Signed-off-by Rikard Falkeborn <[email protected]>Quoted 8 lines
---
Joe Perches sent a series to fix the existing misuses ofGENMASK()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) 0A 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:
#defineGENMASK_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
__GENMASKInconsistent 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 ofBUILD_BUG_OR_ZERO(to avoid GENMASK be of typesize_t) to GENMASK andGENMASK_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
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 wantedGENMASK_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
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 wantedGENMASK_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?
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 wantedGENMASK_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_ZEROreturnssize_tregardless of inputs. I was worried that on some platform,size_twould 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
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 wantedGENMASK_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_ZEROreturnssize_tregardless of inputs. I was worried that on some platform,size_twould 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.
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 wantedGENMASK_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_ZEROreturnssize_tregardless of inputs. I was worried that on some platform,size_twould 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
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 wantedGENMASK_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_ZEROreturnssize_tregardless of inputs. I was worried that on some platform,size_twould 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 longfoo(unsigned long in_bits){ return in_bits & GENMASK(5, 3); }However, you cannot include <
linux/kernel.h> from <linux/bits.h>. See the log of8bd9cb51daac89337295b6f037b0486911e1b408This 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
Joe Perches
maintainerRe: [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_pbut 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)) \
})Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs
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_pbut 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.
Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs
In reply to Rikard FalkebornQuoted 54 lines · Rikard Falkeborn
GENMASK()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON(), and__is_constexpr()must be used instead of__builtin_constant_p().Commit
95b980d62d52("linux/bits.h: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. Since neitherBUILD_BUG_OR_ZERO()or__is_constexpr()are asm compatible, disable the checks if the file is included in an asm file.Signed-off-by Rikard Falkeborn <[email protected]>---
Joe Perches sent a series to fix the existing misuses ofGENMASK()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@@ -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
Joe Perches
maintainerRe: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs
Quoted 31 lines · Masahiro Yamada
Quoted 29 lines · Rikard Falkeborn
GENMASK()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON(), and__is_constexpr()must be used instead of__builtin_constant_p().Commit
95b980d62d52("linux/bits.h: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. Since neitherBUILD_BUG_OR_ZERO()or__is_constexpr()are asm compatible, disable the checks if the file is included in an asm file.Signed-off-by Rikard Falkeborn <[email protected]>---
Joe Perches sent a series to fix the existing misuses ofGENMASK()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))
#defineGENMASK_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.
Re: [PATCH] linux/bits.h: Add compile time sanity check of GENMASK inputs
Quoted 14 lines · Joe Perches
Quoted 13 lines · Masahiro Yamada
Quoted 3 lines · Rikard Falkeborn
GENMASK()andGENMASK_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))
#defineGENMASK_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_bitandlow_bitor high and low.
Agreed.
PATCH v2 1/2 linux/bits.h: Clarify macro argument names
In reply to Rikard FalkebornBe 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
@@ -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
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
@@ -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
Joe Perches
maintainerRe: [PATCH v2 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs
Quoted 42 lines · Rikard Falkeborn
GENMASK()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON(), and__is_constexpr()must be used instead of__builtin_constant_p().If successful,
BUILD_BUG_OR_ZERO()returns 0 of typesize_t. To avoid problems with implicit conversions, cast the result ofBUILD_BUG_OR_ZEROto unsigned long.Since both
BUILD_BUG_ON_ZERO()and__is_constexpr()only usessizeof()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: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. Since neitherBUILD_BUG_OR_ZERO()or__is_constexpr()are asm compatible, disable the checks if the file is included in an asm file.Signed-off-by Rikard Falkeborn <[email protected]>---
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)
Re: [PATCH v2 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs
In reply to Rikard FalkebornQuoted 27 lines · Rikard Falkeborn
GENMASK()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON(), and__is_constexpr()must be used instead of__builtin_constant_p().If successful,
BUILD_BUG_OR_ZERO()returns 0 of typesize_t. To avoid problems with implicit conversions, cast the result ofBUILD_BUG_OR_ZEROto unsigned long.Since both
BUILD_BUG_ON_ZERO()and__is_constexpr()only usessizeof()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: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. Since neitherBUILD_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
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()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON(), and__is_constexpr()must be used instead of__builtin_constant_p().If successful,
BUILD_BUG_OR_ZERO()returns 0 of typesize_t. To avoid problems with implicit conversions, cast the result ofBUILD_BUG_OR_ZEROto unsigned long.Since both
BUILD_BUG_ON_ZERO()and__is_constexpr()only usessizeof()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: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. Since neitherBUILD_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
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()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON(), and__is_constexpr()must be used instead of__builtin_constant_p().If successful,
BUILD_BUG_OR_ZERO()returns 0 of typesize_t. To avoid problems with implicit conversions, cast the result ofBUILD_BUG_OR_ZEROto unsigned long.Since both
BUILD_BUG_ON_ZERO()and__is_constexpr()only usessizeof()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: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. Since neitherBUILD_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
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()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON(), and__is_constexpr()must be used instead of__builtin_constant_p().If successful,
BUILD_BUG_OR_ZERO()returns 0 of typesize_t. To avoid problems with implicit conversions, cast the result ofBUILD_BUG_OR_ZEROto unsigned long.Since both
BUILD_BUG_ON_ZERO()and__is_constexpr()only usessizeof()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: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. Since neitherBUILD_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
Joe Perches
maintainerRe: [PATCH v2 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs
In reply to Masahiro YamadaQuoted 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 macroThese 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.
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
Joe Perches
maintainerRe: [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: 73is 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/shhas 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.
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: 73is 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/shhas 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
kbuild test robot
build botRe: [PATCH v2 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs
In reply to Rikard FalkebornThank 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
kbuild test robot
build botRe: [PATCH v2 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs
In reply to Rikard FalkebornThank 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
Re: [PATCH v2 1/2] linux/bits.h: Clarify macro argument names
In reply to Rikard FalkebornQuoted 4 lines · Rikard Falkeborn
Be a little more verbose to improve readability.
Signed-off-by Rikard Falkeborn <[email protected]>
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 v2include/linux/bits.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)include/linux/bits.h +8
-9@@ -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
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.
Signed-off-by Rikard Falkeborn <[email protected]>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.
Joe Perches
maintainerRe: [PATCH v2 1/2] linux/bits.h: Clarify macro argument names
In reply to Masahiro YamadaQuoted 8 lines · Masahiro Yamada
Quoted 3 lines · Rikard Falkeborn
Be a little more verbose to improve readability.
Signed-off-by Rikard Falkeborn <[email protected]>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 v2include/linux/bits.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)include/linux/bits.h +8
-9@@ -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
v3 cover Add compile time sanity check of GENMASK inputs
In reply to Rikard FalkebornHello,
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
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
@@ -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
@@ -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
tip-bot for Rikard Falkeborn
merge bot[tip:x86/boot] x86/boot: Use common BUILD_BUG_ON
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
@@ -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
@@ -10,6 +10,7 @@/* * Main module for the real-mode kernel code */ +#include <linux/build_bug.h> #include "boot.h" #include "string.h"
tip-bot for Rikard Falkeborn
merge bot[tip:x86/boot] x86/boot: Use common BUILD_BUG_ON
In reply to Rikard Falkebornx86/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
@@ -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
@@ -10,6 +10,7 @@/* * Main module for the real-mode kernel code */ +#include <linux/build_bug.h> #include "boot.h" #include "string.h"
PATCH v3 2/3 linux/build_bug.h: Change type to int
In reply to Rikard FalkebornHaving 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
@@ -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
Re: [PATCH v3 2/3] linux/build_bug.h: Change type to int
Quoted 8 lines · Rikard Falkeborn
Having
BUILD_BUG_ON_ZEROproduce a value of typesize_tleads to awkward casts in cases where the result needs to be signed, or of smaller type thansize_t. To avoid this, cast the value to int instead and rely on implicit type conversions when a larger or unsigned type is needed.Suggested-by Masahiro Yamada <[email protected]>Signed-off-by Rikard Falkeborn <[email protected]>
Quoted 27 lines
Changes in v3:
- This patch is new in v3include/linux/build_bug.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)include/linux/build_bug.h +2
-3@@ -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
PATCH v3 3/3 linux/bits.h: Add compile time sanity check of GENMASK inputs
In reply to Rikard FalkebornGENMASK() 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
@@ -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
Re: [PATCH v3 3/3] linux/bits.h: Add compile time sanity check of GENMASK inputs
Quoted 23 lines · Rikard Falkeborn
GENMASK()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON().
__builtin_constant_pdoes not evaluate is argument, it only checks if it is a constant or not at compile time, and__builtin_choose_exprdoes 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: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. SinceBUILD_BUG_OR_ZERO()is not asm compatible, disable the checks if the file is included in an asm file.Signed-off-by Rikard Falkeborn <[email protected]>
Quoted 63 lines
---
Changes in v3:
- Changed back to shorter macro argument names
- Remove casts and use 0 instead of UL(0) inGENMASK_INPUT_CHECK(), since all results inGENMASK_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 messageJoe 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@@ -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
Re: [PATCH v3 3/3] linux/bits.h: Add compile time sanity check of GENMASK inputs
In reply to Rikard FalkebornHi Rikard,
Quoted 78 lines · Rikard Falkeborn
GENMASK()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON().
__builtin_constant_pdoes not evaluate is argument, it only checks if it is a constant or not at compile time, and__builtin_choose_exprdoes not evaluate the expression that is not chosen. Therefore,GENMASK(x++, 0)does only evaluate x++ once.Commit
95b980d62d52("linux/bits.h: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. SinceBUILD_BUG_OR_ZERO()is not asm compatible, disable the checks if the file is included in an asm file.Signed-off-by Rikard Falkeborn <[email protected]>---
Changes in v3:
- Changed back to shorter macro argument names
- Remove casts and use 0 instead of UL(0) inGENMASK_INPUT_CHECK(), since all results inGENMASK_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 messageJoe 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@@ -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
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()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON().
__builtin_constant_pdoes not evaluate is argument, it only checks if it is a constant or not at compile time, and__builtin_choose_exprdoes not evaluate the expression that is not chosen. Therefore,GENMASK(x++, 0)does only evaluate x++ once.Commit
95b980d62d52("linux/bits.h: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. SinceBUILD_BUG_OR_ZERO()is not asm compatible, disable the checks if the file is included in an asm file.Signed-off-by Rikard Falkeborn <[email protected]>---
Changes in v3:
- Changed back to shorter macro argument names
- Remove casts and use 0 instead of UL(0) inGENMASK_INPUT_CHECK(), since all results inGENMASK_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 messageJoe 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@@ -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()callsGENMASK_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 oralways_inlinedoesn'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
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()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON().
__builtin_constant_pdoes not evaluate is argument, it only checks if it is a constant or not at compile time, and__builtin_choose_exprdoes not evaluate the expression that is not chosen. Therefore,GENMASK(x++, 0)does only evaluate x++ once.Commit
95b980d62d52("linux/bits.h: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. SinceBUILD_BUG_OR_ZERO()is not asm compatible, disable the checks if the file is included in an asm file.Signed-off-by Rikard Falkeborn <[email protected]>---
Changes in v3:
- Changed back to shorter macro argument names
- Remove casts and use 0 instead of UL(0) inGENMASK_INPUT_CHECK(), since all results inGENMASK_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 messageJoe 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@@ -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_expror__builtin_constant_pfor 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()callsGENMASK_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 oralways_inlinedoesn'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
@@ -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
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()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON().
__builtin_constant_pdoes not evaluate is argument, it only checks if it is a constant or not at compile time, and__builtin_choose_exprdoes not evaluate the expression that is not chosen. Therefore,GENMASK(x++, 0)does only evaluate x++ once.Commit
95b980d62d52("linux/bits.h: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. SinceBUILD_BUG_OR_ZERO()is not asm compatible, disable the checks if the file is included in an asm file.Signed-off-by Rikard Falkeborn <[email protected]>---
Changes in v3:
- Changed back to shorter macro argument names
- Remove casts and use 0 instead of UL(0) inGENMASK_INPUT_CHECK(), since all results inGENMASK_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 messageJoe 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@@ -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_expror__builtin_constant_pfor 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()callsGENMASK_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 oralways_inlinedoesn'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@@ -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
Re: [PATCH v3 0/3] Add compile time sanity check of GENMASK inputs
In reply to Rikard FalkebornQuoted 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_ONin x86/boot to avoid a compiler warning about redefiningBUILD_BUG_ON. Instead, use the common one frominclude/.Drop patch 2 in v2 where GENMASK arguments where made more verbose.
Add a cast in the
BUILD_BUG_ON_ZEROmacro change the type to int to avoid the somewhat clumpsy casts ofBUILD_BUG_ON_ZERO. The second patch in this series adds such a cast toBUILD_BUG_ON_ZERO, which makes it possible to avoid casts when usingBUILD_BUG_ON_ZEROin patch 3.
Quoted 8 lines
I have checked all users of
BUILD_BUG_ON_ZEROand 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 usingBUILD_BUG_ON_ZERO?Finally, use
__builtin_constant_pinstead of__is_constexpr. This avoids pulling inkernel.hinbits.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
Re: [PATCH v3 0/3] Add compile time sanity check of GENMASK inputs
In reply to Rikard FalkebornQuoted 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_ONin x86/boot to avoid a compiler warning about redefiningBUILD_BUG_ON. Instead, use the common one frominclude/.Drop patch 2 in v2 where GENMASK arguments where made more verbose.
Add a cast in the
BUILD_BUG_ON_ZEROmacro change the type to int to avoid the somewhat clumpsy casts ofBUILD_BUG_ON_ZERO. The second patch in this series adds such a cast toBUILD_BUG_ON_ZERO, which makes it possible to avoid casts when usingBUILD_BUG_ON_ZEROin patch 3.I have checked all users of
BUILD_BUG_ON_ZEROand 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 usingBUILD_BUG_ON_ZERO?Finally, use
__builtin_constant_pinstead of__is_constexpr. This avoids pulling inkernel.hinbits.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
v4 cover Add compile time sanity check of GENMASK inputs
In reply to Rikard FalkebornHello,
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
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
@@ -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
PATCH v4 2/2 linux/bits.h: Add compile time sanity check of GENMASK inputs
In reply to Rikard FalkebornGENMASK() 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
@@ -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
Re: [Patch v4 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs
Quoted 28 lines · Rikard Falkeborn
GENMASK()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON().
__builtin_constant_pdoes not evaluate is argument, it only checks if it is a constant or not at compile time, and__builtin_choose_exprdoes not evaluate the expression that is not chosen. Therefore,GENMASK(x++, 0)does only evaluate x++ once.Commit
95b980d62d52("linux/bits.h: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. SinceBUILD_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
Signed-off-by Rikard Falkeborn <[email protected]>
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) inGENMASK_INPUT_CHECK(), since all results inGENMASK_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 messageJoe 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@@ -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
Re: [Patch v4 2/2] linux/bits.h: Add compile time sanity check of GENMASK inputs
In reply to Rikard FalkebornQuoted 27 lines · On Wed, 9 Oct 2019 23:45:02 +0200 Rikard Falkeborn…
GENMASK()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON().
__builtin_constant_pdoes not evaluate is argument, it only checks if it is a constant or not at compile time, and__builtin_choose_exprdoes not evaluate the expression that is not chosen. Therefore,GENMASK(x++, 0)does only evaluate x++ once.Commit
95b980d62d52("linux/bits.h: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. SinceBUILD_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.
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" },
^~~~~~~
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()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON().
__builtin_constant_pdoes not evaluate is argument, it only checks if it is a constant or not at compile time, and__builtin_choose_exprdoes not evaluate the expression that is not chosen. Therefore,GENMASK(x++, 0)does only evaluate x++ once.Commit
95b980d62d52("linux/bits.h: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. SinceBUILD_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.
I'm seeing some breakage in code which is newly added in linux-next:
sound/soc/codecs/tas2562.c: In functiontas2562_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 macroGENMASK_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 macroBUILD_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
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()andGENMASK_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
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].
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
@@ -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
Re: [PATCH v5] linux/bits.h: Add compile time sanity check of GENMASK inputs
Quoted 27 lines · Rikard Falkeborn
GENMASK()andGENMASK_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 commit9bdd7bb3a844("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()andGENMASK_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 ofBUILD_BUG_ON().
__builtin_constant_pdoes not evaluate is argument, it only checks if it is a constant or not at compile time, and__builtin_choose_exprdoes not evaluate the expression that is not chosen. Therefore,GENMASK(x++, 0)does only evaluate x++ once.Commit
95b980d62d52("linux/bits.h: makeBIT(),GENMASK(), and friends available in assembly") made the macros inlinux/bits.havailable in assembly. SinceBUILD_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
Signed-off-by Rikard Falkeborn <[email protected]>
-Kees
Quoted 77 lines
Reviewed-by Masahiro Yamada <[email protected]>---
Another attempt to get this merged. I've test built allmodconfig for i386,x86_64and arm64 for linux-next 20200306 without issues. Also, the last known GENMASK issue was just merged into Linus tree [1].Changes in v5:
- Added Masahiros Reviewed-by
- Waited for bugfixes to get mergedChanges 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) inGENMASK_INPUT_CHECK(), since all results inGENMASK_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 messageJoe 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@@ -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
David Miller
maintainerFrom: 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.
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
@@ -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
@@ -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