diff options
author | Steffen Trumtrar <s.trumtrar@pengutronix.de> | 2015-12-08 12:40:16 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2016-02-03 17:14:10 +0100 |
commit | 7ffff00dfdcd4ea28b9edf8420dac8ba53061491 (patch) | |
tree | 7d03653b4b2903d39af0fa882e9847dc7df4534a /include/linux/bitops.h | |
parent | ba24403f24cfd8c461e9b087a81d2e16efed418f (diff) | |
download | barebox-7ffff00dfdcd4ea28b9edf8420dac8ba53061491.tar.gz barebox-7ffff00dfdcd4ea28b9edf8420dac8ba53061491.tar.xz |
bitops: Fix shift overflow in GENMASK macros
Based on the original patch for linux:
commit 00b4d9a14125f1e51874def2b9de6092e007412d
Author: Maxime COQUELIN <maxime.coquelin@st.com>
Date: Thu Nov 6 10:54:19 2014
On some 32 bits architectures, including x86, GENMASK(31, 0) returns 0
instead of the expected ~0UL.
This is the same on some 64 bits architectures with GENMASK_ULL(63, 0).
This is due to an overflow in the shift operand, 1 << 32 for GENMASK,
1 << 64 for GENMASK_ULL.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
Diffstat (limited to 'include/linux/bitops.h')
-rw-r--r-- | include/linux/bitops.h | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/include/linux/bitops.h b/include/linux/bitops.h index f3a740c461..31345c219d 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h @@ -18,8 +18,11 @@ * position @h. For example * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. */ -#define GENMASK(h, l) (((U32_C(1) << ((h) - (l) + 1)) - 1) << (l)) -#define GENMASK_ULL(h, l) (((U64_C(1) << ((h) - (l) + 1)) - 1) << (l)) +#define GENMASK(h, l) \ + (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) + +#define GENMASK_ULL(h, l) \ + (((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h)))) extern unsigned int __sw_hweight8(unsigned int w); extern unsigned int __sw_hweight16(unsigned int w); |