2018-06-19 12:53:08 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
#ifndef __LINUX_BITS_H
|
|
|
|
#define __LINUX_BITS_H
|
linux/bits.h: make BIT(), GENMASK(), and friends available in assembly
BIT(), GENMASK(), etc. are useful to define register bits of hardware.
However, low-level code is often written in assembly, where they are
not available due to the hard-coded 1UL, 0UL.
In fact, in-kernel headers such as arch/arm64/include/asm/sysreg.h
use _BITUL() instead of BIT() so that the register bit macros are
available in assembly.
Using macros in include/uapi/linux/const.h have two reasons:
[1] For use in uapi headers
We should use underscore-prefixed variants for user-space.
[2] For use in assembly code
Since _BITUL() uses UL(1) instead of 1UL, it can be used as an
alternative of BIT().
For [2], it is pretty easy to change BIT() etc. for use in assembly.
This allows to replace _BUTUL() in kernel-space headers with BIT().
Link: http://lkml.kernel.org/r/20190609153941.17249-1-yamada.masahiro@socionext.com
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2019-07-16 23:26:57 +00:00
|
|
|
|
|
|
|
#include <linux/const.h>
|
2020-03-20 14:53:27 +00:00
|
|
|
#include <vdso/bits.h>
|
2023-12-12 16:15:28 +00:00
|
|
|
#include <uapi/linux/bits.h>
|
2018-06-19 12:53:08 +00:00
|
|
|
#include <asm/bitsperlong.h>
|
|
|
|
|
linux/bits.h: make BIT(), GENMASK(), and friends available in assembly
BIT(), GENMASK(), etc. are useful to define register bits of hardware.
However, low-level code is often written in assembly, where they are
not available due to the hard-coded 1UL, 0UL.
In fact, in-kernel headers such as arch/arm64/include/asm/sysreg.h
use _BITUL() instead of BIT() so that the register bit macros are
available in assembly.
Using macros in include/uapi/linux/const.h have two reasons:
[1] For use in uapi headers
We should use underscore-prefixed variants for user-space.
[2] For use in assembly code
Since _BITUL() uses UL(1) instead of 1UL, it can be used as an
alternative of BIT().
For [2], it is pretty easy to change BIT() etc. for use in assembly.
This allows to replace _BUTUL() in kernel-space headers with BIT().
Link: http://lkml.kernel.org/r/20190609153941.17249-1-yamada.masahiro@socionext.com
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2019-07-16 23:26:57 +00:00
|
|
|
#define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG))
|
2018-06-19 12:53:08 +00:00
|
|
|
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
|
linux/bits.h: make BIT(), GENMASK(), and friends available in assembly
BIT(), GENMASK(), etc. are useful to define register bits of hardware.
However, low-level code is often written in assembly, where they are
not available due to the hard-coded 1UL, 0UL.
In fact, in-kernel headers such as arch/arm64/include/asm/sysreg.h
use _BITUL() instead of BIT() so that the register bit macros are
available in assembly.
Using macros in include/uapi/linux/const.h have two reasons:
[1] For use in uapi headers
We should use underscore-prefixed variants for user-space.
[2] For use in assembly code
Since _BITUL() uses UL(1) instead of 1UL, it can be used as an
alternative of BIT().
For [2], it is pretty easy to change BIT() etc. for use in assembly.
This allows to replace _BUTUL() in kernel-space headers with BIT().
Link: http://lkml.kernel.org/r/20190609153941.17249-1-yamada.masahiro@socionext.com
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2019-07-16 23:26:57 +00:00
|
|
|
#define BIT_ULL_MASK(nr) (ULL(1) << ((nr) % BITS_PER_LONG_LONG))
|
2018-06-19 12:53:08 +00:00
|
|
|
#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG)
|
|
|
|
#define BITS_PER_BYTE 8
|
bits: introduce fixed-type GENMASK_U*()
Add GENMASK_TYPE() which generalizes __GENMASK() to support different
types, and implement fixed-types versions of GENMASK() based on it.
The fixed-type version allows more strict checks to the min/max values
accepted, which is useful for defining registers like implemented by
i915 and xe drivers with their REG_GENMASK*() macros.
The strict checks rely on shift-count-overflow compiler check to fail
the build if a number outside of the range allowed is passed.
Example:
#define FOO_MASK GENMASK_U32(33, 4)
will generate a warning like:
include/linux/bits.h:51:27: error: right shift count >= width of type [-Werror=shift-count-overflow]
51 | type_max(t) >> (BITS_PER_TYPE(t) - 1 - (h)))))
| ^~
The result is casted to the corresponding fixed width type. For
example, GENMASK_U8() returns an u8. Note that because of the C
promotion rules, GENMASK_U8() and GENMASK_U16() will immediately be
promoted to int if used in an expression. Regardless, the main goal is
not to get the correct type, but rather to enforce more checks at
compile time.
While GENMASK_TYPE() is crafted to cover all variants, including the
already existing GENMASK(), GENMASK_ULL() and GENMASK_U128(), for the
moment, only use it for the newly introduced GENMASK_U*(). The
consolidation will be done in a separate change.
Co-developed-by: Yury Norov <yury.norov@gmail.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Acked-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Yury Norov <yury.norov@gmail.com>
2025-03-25 15:59:57 +00:00
|
|
|
#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
|
2018-06-19 12:53:08 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a contiguous bitmask starting at bit position @l and ending at
|
|
|
|
* position @h. For example
|
|
|
|
* GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
|
|
|
|
*/
|
2020-07-08 17:48:35 +00:00
|
|
|
#if !defined(__ASSEMBLY__)
|
2025-03-25 15:59:56 +00:00
|
|
|
|
bits: introduce fixed-type GENMASK_U*()
Add GENMASK_TYPE() which generalizes __GENMASK() to support different
types, and implement fixed-types versions of GENMASK() based on it.
The fixed-type version allows more strict checks to the min/max values
accepted, which is useful for defining registers like implemented by
i915 and xe drivers with their REG_GENMASK*() macros.
The strict checks rely on shift-count-overflow compiler check to fail
the build if a number outside of the range allowed is passed.
Example:
#define FOO_MASK GENMASK_U32(33, 4)
will generate a warning like:
include/linux/bits.h:51:27: error: right shift count >= width of type [-Werror=shift-count-overflow]
51 | type_max(t) >> (BITS_PER_TYPE(t) - 1 - (h)))))
| ^~
The result is casted to the corresponding fixed width type. For
example, GENMASK_U8() returns an u8. Note that because of the C
promotion rules, GENMASK_U8() and GENMASK_U16() will immediately be
promoted to int if used in an expression. Regardless, the main goal is
not to get the correct type, but rather to enforce more checks at
compile time.
While GENMASK_TYPE() is crafted to cover all variants, including the
already existing GENMASK(), GENMASK_ULL() and GENMASK_U128(), for the
moment, only use it for the newly introduced GENMASK_U*(). The
consolidation will be done in a separate change.
Co-developed-by: Yury Norov <yury.norov@gmail.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Acked-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Yury Norov <yury.norov@gmail.com>
2025-03-25 15:59:57 +00:00
|
|
|
/*
|
|
|
|
* Missing asm support
|
|
|
|
*
|
2025-03-25 15:59:58 +00:00
|
|
|
* GENMASK_U*() and BIT_U*() depend on BITS_PER_TYPE() which relies on sizeof(),
|
bits: introduce fixed-type GENMASK_U*()
Add GENMASK_TYPE() which generalizes __GENMASK() to support different
types, and implement fixed-types versions of GENMASK() based on it.
The fixed-type version allows more strict checks to the min/max values
accepted, which is useful for defining registers like implemented by
i915 and xe drivers with their REG_GENMASK*() macros.
The strict checks rely on shift-count-overflow compiler check to fail
the build if a number outside of the range allowed is passed.
Example:
#define FOO_MASK GENMASK_U32(33, 4)
will generate a warning like:
include/linux/bits.h:51:27: error: right shift count >= width of type [-Werror=shift-count-overflow]
51 | type_max(t) >> (BITS_PER_TYPE(t) - 1 - (h)))))
| ^~
The result is casted to the corresponding fixed width type. For
example, GENMASK_U8() returns an u8. Note that because of the C
promotion rules, GENMASK_U8() and GENMASK_U16() will immediately be
promoted to int if used in an expression. Regardless, the main goal is
not to get the correct type, but rather to enforce more checks at
compile time.
While GENMASK_TYPE() is crafted to cover all variants, including the
already existing GENMASK(), GENMASK_ULL() and GENMASK_U128(), for the
moment, only use it for the newly introduced GENMASK_U*(). The
consolidation will be done in a separate change.
Co-developed-by: Yury Norov <yury.norov@gmail.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Acked-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Yury Norov <yury.norov@gmail.com>
2025-03-25 15:59:57 +00:00
|
|
|
* something not available in asm. Nevertheless, fixed width integers is a C
|
|
|
|
* concept. Assembly code can rely on the long and long long versions instead.
|
|
|
|
*/
|
|
|
|
|
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
Signed-off-by: Rikard Falkeborn <rikard.falkeborn@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Haren Myneni <haren@us.ibm.com>
Cc: Joe Perches <joe@perches.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: lkml <linux-kernel@vger.kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20200308193954.2372399-1-rikard.falkeborn@gmail.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2020-04-07 03:10:38 +00:00
|
|
|
#include <linux/build_bug.h>
|
2024-11-13 17:18:33 +00:00
|
|
|
#include <linux/compiler.h>
|
bits: introduce fixed-type GENMASK_U*()
Add GENMASK_TYPE() which generalizes __GENMASK() to support different
types, and implement fixed-types versions of GENMASK() based on it.
The fixed-type version allows more strict checks to the min/max values
accepted, which is useful for defining registers like implemented by
i915 and xe drivers with their REG_GENMASK*() macros.
The strict checks rely on shift-count-overflow compiler check to fail
the build if a number outside of the range allowed is passed.
Example:
#define FOO_MASK GENMASK_U32(33, 4)
will generate a warning like:
include/linux/bits.h:51:27: error: right shift count >= width of type [-Werror=shift-count-overflow]
51 | type_max(t) >> (BITS_PER_TYPE(t) - 1 - (h)))))
| ^~
The result is casted to the corresponding fixed width type. For
example, GENMASK_U8() returns an u8. Note that because of the C
promotion rules, GENMASK_U8() and GENMASK_U16() will immediately be
promoted to int if used in an expression. Regardless, the main goal is
not to get the correct type, but rather to enforce more checks at
compile time.
While GENMASK_TYPE() is crafted to cover all variants, including the
already existing GENMASK(), GENMASK_ULL() and GENMASK_U128(), for the
moment, only use it for the newly introduced GENMASK_U*(). The
consolidation will be done in a separate change.
Co-developed-by: Yury Norov <yury.norov@gmail.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Acked-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Yury Norov <yury.norov@gmail.com>
2025-03-25 15:59:57 +00:00
|
|
|
#include <linux/overflow.h>
|
2025-03-25 15:59:56 +00:00
|
|
|
|
2024-11-13 17:18:33 +00:00
|
|
|
#define GENMASK_INPUT_CHECK(h, l) BUILD_BUG_ON_ZERO(const_true((l) > (h)))
|
2025-03-25 15:59:56 +00:00
|
|
|
|
bits: introduce fixed-type GENMASK_U*()
Add GENMASK_TYPE() which generalizes __GENMASK() to support different
types, and implement fixed-types versions of GENMASK() based on it.
The fixed-type version allows more strict checks to the min/max values
accepted, which is useful for defining registers like implemented by
i915 and xe drivers with their REG_GENMASK*() macros.
The strict checks rely on shift-count-overflow compiler check to fail
the build if a number outside of the range allowed is passed.
Example:
#define FOO_MASK GENMASK_U32(33, 4)
will generate a warning like:
include/linux/bits.h:51:27: error: right shift count >= width of type [-Werror=shift-count-overflow]
51 | type_max(t) >> (BITS_PER_TYPE(t) - 1 - (h)))))
| ^~
The result is casted to the corresponding fixed width type. For
example, GENMASK_U8() returns an u8. Note that because of the C
promotion rules, GENMASK_U8() and GENMASK_U16() will immediately be
promoted to int if used in an expression. Regardless, the main goal is
not to get the correct type, but rather to enforce more checks at
compile time.
While GENMASK_TYPE() is crafted to cover all variants, including the
already existing GENMASK(), GENMASK_ULL() and GENMASK_U128(), for the
moment, only use it for the newly introduced GENMASK_U*(). The
consolidation will be done in a separate change.
Co-developed-by: Yury Norov <yury.norov@gmail.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Acked-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Yury Norov <yury.norov@gmail.com>
2025-03-25 15:59:57 +00:00
|
|
|
/*
|
|
|
|
* Generate a mask for the specified type @t. Additional checks are made to
|
|
|
|
* guarantee the value returned fits in that type, relying on
|
|
|
|
* -Wshift-count-overflow compiler check to detect incompatible arguments.
|
|
|
|
* For example, all these create build errors or warnings:
|
|
|
|
*
|
|
|
|
* - GENMASK(15, 20): wrong argument order
|
|
|
|
* - GENMASK(72, 15): doesn't fit unsigned long
|
|
|
|
* - GENMASK_U32(33, 15): doesn't fit in a u32
|
|
|
|
*/
|
|
|
|
#define GENMASK_TYPE(t, h, l) \
|
|
|
|
((t)(GENMASK_INPUT_CHECK(h, l) + \
|
|
|
|
(type_max(t) << (l) & \
|
|
|
|
type_max(t) >> (BITS_PER_TYPE(t) - 1 - (h)))))
|
|
|
|
|
|
|
|
#define GENMASK_U8(h, l) GENMASK_TYPE(u8, h, l)
|
|
|
|
#define GENMASK_U16(h, l) GENMASK_TYPE(u16, h, l)
|
|
|
|
#define GENMASK_U32(h, l) GENMASK_TYPE(u32, h, l)
|
|
|
|
#define GENMASK_U64(h, l) GENMASK_TYPE(u64, h, l)
|
|
|
|
|
2025-03-25 15:59:58 +00:00
|
|
|
/*
|
|
|
|
* Fixed-type variants of BIT(), with additional checks like GENMASK_TYPE(). The
|
|
|
|
* following examples generate compiler warnings due to -Wshift-count-overflow:
|
|
|
|
*
|
|
|
|
* - BIT_U8(8)
|
|
|
|
* - BIT_U32(-1)
|
|
|
|
* - BIT_U32(40)
|
|
|
|
*/
|
|
|
|
#define BIT_INPUT_CHECK(type, nr) \
|
|
|
|
BUILD_BUG_ON_ZERO(const_true((nr) >= BITS_PER_TYPE(type)))
|
|
|
|
|
|
|
|
#define BIT_TYPE(type, nr) ((type)(BIT_INPUT_CHECK(type, nr) + BIT_ULL(nr)))
|
|
|
|
|
|
|
|
#define BIT_U8(nr) BIT_TYPE(u8, nr)
|
|
|
|
#define BIT_U16(nr) BIT_TYPE(u16, nr)
|
|
|
|
#define BIT_U32(nr) BIT_TYPE(u32, nr)
|
|
|
|
#define BIT_U64(nr) BIT_TYPE(u64, nr)
|
|
|
|
|
2025-03-25 15:59:56 +00:00
|
|
|
#else /* defined(__ASSEMBLY__) */
|
|
|
|
|
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
Signed-off-by: Rikard Falkeborn <rikard.falkeborn@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Haren Myneni <haren@us.ibm.com>
Cc: Joe Perches <joe@perches.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: lkml <linux-kernel@vger.kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20200308193954.2372399-1-rikard.falkeborn@gmail.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2020-04-07 03:10:38 +00:00
|
|
|
/*
|
|
|
|
* 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
|
2025-03-25 15:59:56 +00:00
|
|
|
|
|
|
|
#endif /* !defined(__ASSEMBLY__) */
|
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
Signed-off-by: Rikard Falkeborn <rikard.falkeborn@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Haren Myneni <haren@us.ibm.com>
Cc: Joe Perches <joe@perches.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: lkml <linux-kernel@vger.kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20200308193954.2372399-1-rikard.falkeborn@gmail.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2020-04-07 03:10:38 +00:00
|
|
|
|
|
|
|
#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))
|
2018-06-19 12:53:08 +00:00
|
|
|
|
2024-08-22 04:48:52 +00:00
|
|
|
#if !defined(__ASSEMBLY__)
|
|
|
|
/*
|
|
|
|
* Missing asm support
|
|
|
|
*
|
|
|
|
* __GENMASK_U128() depends on _BIT128() which would not work
|
2025-03-05 14:59:32 +00:00
|
|
|
* in the asm code, as it shifts an 'unsigned __int128' data
|
2024-08-22 04:48:52 +00:00
|
|
|
* type instead of direct representation of 128 bit constants
|
|
|
|
* such as long and unsigned long. The fundamental problem is
|
|
|
|
* that a 128 bit constant will get silently truncated by the
|
|
|
|
* gcc compiler.
|
|
|
|
*/
|
|
|
|
#define GENMASK_U128(h, l) \
|
|
|
|
(GENMASK_INPUT_CHECK(h, l) + __GENMASK_U128(h, l))
|
|
|
|
#endif
|
|
|
|
|
2018-06-19 12:53:08 +00:00
|
|
|
#endif /* __LINUX_BITS_H */
|