From: David Laight <david.laight.linux@gmail.com>
The definition of BIT() was moved from linux/bits.h to vdso/bits.h to
isolate the vdso from 'normal' kernel headers.
BIT_ULL() was then moved to be defined in the same place for consistency.
Since then linux/bits.h had gained BIT_Unn() and it really makes sense
for BIT() and BIT_ULL() to be defined in the same place.
Move BIT_ULL() and make code that include both headers use the definition
of BIT() from linux/bits.h
Add BIT_U128() for completness.
This lets BIT() pick up the extra compile time checks for W=[1c] builds
that detect errors like:
long foo(void) { int x = 64; return BIT(x); }
For which clang (silently) just generates a 'return' instruction.
Note that nothing the the x86-64 build relies on the definition in
vdso/bits.h, linux/bits.h is always included.
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
include/linux/bits.h | 7 ++++++-
include/vdso/bits.h | 2 +-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/include/linux/bits.h b/include/linux/bits.h
index 0f559038981d..3dd32b9eef35 100644
--- a/include/linux/bits.h
+++ b/include/linux/bits.h
@@ -2,7 +2,6 @@
#ifndef __LINUX_BITS_H
#define __LINUX_BITS_H
-#include <vdso/bits.h>
#include <uapi/linux/bits.h>
#define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG))
@@ -89,10 +88,16 @@ int BIT_INPUT_CHECK_FAIL(void) __compiletime_error("Bit number out of range");
((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
#endif /* defined(__ASSEMBLY__) */
+/* Prefer this definition of BIT() to the one in vdso/bits.h */
+#undef BIT
+#define __VDSO_BITS_H
+#define BIT(nr) BIT_TYPE(unsigned long, nr)
+#define BIT_ULL(nr) BIT_TYPE(unsigned long long, 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)
+#define BIT_U128(nr) BIT_TYPE(u128, nr)
#if defined(__ASSEMBLY__)
diff --git a/include/vdso/bits.h b/include/vdso/bits.h
index 388b212088ea..a6ac1e6b637c 100644
--- a/include/vdso/bits.h
+++ b/include/vdso/bits.h
@@ -4,7 +4,7 @@
#include <vdso/const.h>
+/* Most code picks up BIT() from linux/bits.h */
#define BIT(nr) (UL(1) << (nr))
-#define BIT_ULL(nr) (ULL(1) << (nr))
#endif /* __VDSO_BITS_H */
--
2.39.5
On Wed, Jan 21 2026 at 14:57, david laight linux wrote:
TLDR: Not going to happen. Period.
> Move BIT_ULL() and make code that include both headers use the definition
> of BIT() from linux/bits.h
> Add BIT_U128() for completness.
1) How is that related to $Subject?
2) It's clearly documented that patches should not do different things
at once.
3) It's also documented that stuff is only added when there is a use
case. I can't find one.
> Note that nothing the the x86-64 build relies on the definition in
> vdso/bits.h, linux/bits.h is always included.
Wrong. The x86-64 build includes vdso/bits.h for the VDSO build.
> @@ -2,7 +2,6 @@
> #ifndef __LINUX_BITS_H
> #define __LINUX_BITS_H
>
> -#include <vdso/bits.h>
> #include <uapi/linux/bits.h>
>
> #define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG))
> @@ -89,10 +88,16 @@ int BIT_INPUT_CHECK_FAIL(void) __compiletime_error("Bit number out of range");
> ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
> #endif /* defined(__ASSEMBLY__) */
>
> +/* Prefer this definition of BIT() to the one in vdso/bits.h */
> +#undef BIT
That's a horrible sloppy hack.
> +#define __VDSO_BITS_H
And this even more so.
> +#define BIT(nr) BIT_TYPE(unsigned long, nr)
> +#define BIT_ULL(nr) BIT_TYPE(unsigned long long, nr)
Aside of that you sloppily kept the comment above all of this intact,
which does not make any sense at all after this change. It says:
/*
* 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)
*/
I have to admit that you are at least consistently sloppy.
> #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)
> +#define BIT_U128(nr) BIT_TYPE(u128, nr)
What's wrong with the obvious solution of moving all this BIT_XX() muck
into vdso/bit.h?
Especially as you say in your changelog word salad:
> This lets BIT() pick up the extra compile time checks for W=[1c] builds
> that detect errors like:
> long foo(void) { int x = 64; return BIT(x); }
> For which clang (silently) just generates a 'return' instruction.
Letting the VDSO build have the same checks with a W=1 build would be
too sensible, right?
It's not rocket science to achieve that. See below.
That's admittedly a hack too, but a more palatable hack and I'm just
including it for illustration.
Just for the record: I definitely spent less time hacking that up than I
wasted reviewing and replying to your slop.
The proper thing to do is to move all the stuff which is neither vdso
nor kernel specific into a separate include/$BIKESHEDTHENAME/ directory
and sort out that ever recurring problem of VDSO vs. kernel builds once
and forever. That's not rocket science either.
That'd be too reasonable and tasteful, but not convoluted and sloppy
enough, right?
Thanks,
tglx
---
include/vdso/compiler.h | 76 ++++++++++++++++++++++++++++++++++++++++++++++
include/linux/bits.h | 20 ------------
include/linux/compiler.h | 71 ------------------------------------------
include/vdso/bits.h | 23 ++++++++++++-
4 files changed, 97 insertions(+), 93 deletions(-)
---
--- a/include/linux/bits.h
+++ b/include/linux/bits.h
@@ -9,8 +9,6 @@
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
#define BIT_ULL_MASK(nr) (ULL(1) << ((nr) % BITS_PER_LONG_LONG))
#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG)
-#define BITS_PER_BYTE 8
-#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
/*
* Create a contiguous bitmask starting at bit position @l and ending at
@@ -57,24 +55,6 @@
#define GENMASK_U64(h, l) GENMASK_TYPE(u64, h, l)
#define GENMASK_U128(h, l) GENMASK_TYPE(u128, h, l)
-/*
- * 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)
-
#else /* defined(__ASSEMBLY__) */
/*
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -279,53 +279,6 @@ static inline void *offset_to_ptr(const
___ADDRESSABLE(sym, __section(".discard.addressable"))
/*
- * This returns a constant expression while determining if an argument is
- * a constant expression, most importantly without evaluating the argument.
- * Glory to Martin Uecker <Martin.Uecker@med.uni-goettingen.de>
- *
- * Details:
- * - sizeof() return an integer constant expression, and does not evaluate
- * the value of its operand; it only examines the type of its operand.
- * - The results of comparing two integer constant expressions is also
- * an integer constant expression.
- * - The first literal "8" isn't important. It could be any literal value.
- * - The second literal "8" is to avoid warnings about unaligned pointers;
- * this could otherwise just be "1".
- * - (long)(x) is used to avoid warnings about 64-bit types on 32-bit
- * architectures.
- * - The C Standard defines "null pointer constant", "(void *)0", as
- * distinct from other void pointers.
- * - If (x) is an integer constant expression, then the "* 0l" resolves
- * it into an integer constant expression of value 0. Since it is cast to
- * "void *", this makes the second operand a null pointer constant.
- * - If (x) is not an integer constant expression, then the second operand
- * resolves to a void pointer (but not a null pointer constant: the value
- * is not an integer constant 0).
- * - The conditional operator's third operand, "(int *)8", is an object
- * pointer (to type "int").
- * - The behavior (including the return type) of the conditional operator
- * ("operand1 ? operand2 : operand3") depends on the kind of expressions
- * given for the second and third operands. This is the central mechanism
- * of the macro:
- * - When one operand is a null pointer constant (i.e. when x is an integer
- * constant expression) and the other is an object pointer (i.e. our
- * third operand), the conditional operator returns the type of the
- * object pointer operand (i.e. "int *"). Here, within the sizeof(), we
- * would then get:
- * sizeof(*((int *)(...)) == sizeof(int) == 4
- * - When one operand is a void pointer (i.e. when x is not an integer
- * constant expression) and the other is an object pointer (i.e. our
- * third operand), the conditional operator returns a "void *" type.
- * Here, within the sizeof(), we would then get:
- * sizeof(*((void *)(...)) == sizeof(void) == 1
- * - The equality comparison to "sizeof(int)" therefore depends on (x):
- * sizeof(int) == sizeof(int) (x) was a constant expression
- * sizeof(int) != sizeof(void) (x) was not a constant expression
- */
-#define __is_constexpr(x) \
- (sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8)))
-
-/*
* Whether 'type' is a signed type or an unsigned type. Supports scalar types,
* bool and also pointer types.
*/
@@ -342,28 +295,6 @@ static inline void *offset_to_ptr(const
#define statically_true(x) (__builtin_constant_p(x) && (x))
/*
- * Similar to statically_true() but produces a constant expression
- *
- * To be used in conjunction with macros, such as BUILD_BUG_ON_ZERO(),
- * which require their input to be a constant expression and for which
- * statically_true() would otherwise fail.
- *
- * This is a trade-off: const_true() requires all its operands to be
- * compile time constants. Else, it would always returns false even on
- * the most trivial cases like:
- *
- * true || non_const_var
- *
- * On the opposite, statically_true() is able to fold more complex
- * tautologies and will return true on expressions such as:
- *
- * !(non_const_var * 8 % 4)
- *
- * For the general case, statically_true() is better.
- */
-#define const_true(x) __builtin_choose_expr(__is_constexpr(x), x, false)
-
-/*
* This is needed in functions which generate the stack canary, see
* arch/x86/kernel/smpboot.c::start_secondary() for an example.
*/
--- a/include/vdso/bits.h
+++ b/include/vdso/bits.h
@@ -2,9 +2,26 @@
#ifndef __VDSO_BITS_H
#define __VDSO_BITS_H
+#include <vdso/compiler.h>
#include <vdso/const.h>
-#define BIT(nr) (UL(1) << (nr))
-#define BIT_ULL(nr) (ULL(1) << (nr))
+#if !defined(__ASSEMBLY__)
-#endif /* __VDSO_BITS_H */
+#define BITS_PER_BYTE 8
+#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
+
+/* Check for BIT() similar to GENMASK_TYPE() to catch shift count overflow at compile time */
+#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) + (ULL(1) << (nr))))
+
+#define BIT(nr) BIT_TYPE(unsigned long, nr)
+#define BIT_ULL(nr) BIT_TYPE(unsigned long long, 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)
+
+#endif /* !__ASSEMBLY__ */
+#endif /* __VDSO_BITS_H */
--- /dev/null
+++ b/include/vdso/compiler.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __VDSO_COMPILER_H
+#define __VDSO_COMPILER_H
+
+#include <linux/compiler_types.h>
+
+/*
+ * This returns a constant expression while determining if an argument is
+ * a constant expression, most importantly without evaluating the argument.
+ * Glory to Martin Uecker <Martin.Uecker@med.uni-goettingen.de>
+ *
+ * Details:
+ * - sizeof() return an integer constant expression, and does not evaluate
+ * the value of its operand; it only examines the type of its operand.
+ * - The results of comparing two integer constant expressions is also
+ * an integer constant expression.
+ * - The first literal "8" isn't important. It could be any literal value.
+ * - The second literal "8" is to avoid warnings about unaligned pointers;
+ * this could otherwise just be "1".
+ * - (long)(x) is used to avoid warnings about 64-bit types on 32-bit
+ * architectures.
+ * - The C Standard defines "null pointer constant", "(void *)0", as
+ * distinct from other void pointers.
+ * - If (x) is an integer constant expression, then the "* 0l" resolves
+ * it into an integer constant expression of value 0. Since it is cast to
+ * "void *", this makes the second operand a null pointer constant.
+ * - If (x) is not an integer constant expression, then the second operand
+ * resolves to a void pointer (but not a null pointer constant: the value
+ * is not an integer constant 0).
+ * - The conditional operator's third operand, "(int *)8", is an object
+ * pointer (to type "int").
+ * - The behavior (including the return type) of the conditional operator
+ * ("operand1 ? operand2 : operand3") depends on the kind of expressions
+ * given for the second and third operands. This is the central mechanism
+ * of the macro:
+ * - When one operand is a null pointer constant (i.e. when x is an integer
+ * constant expression) and the other is an object pointer (i.e. our
+ * third operand), the conditional operator returns the type of the
+ * object pointer operand (i.e. "int *"). Here, within the sizeof(), we
+ * would then get:
+ * sizeof(*((int *)(...)) == sizeof(int) == 4
+ * - When one operand is a void pointer (i.e. when x is not an integer
+ * constant expression) and the other is an object pointer (i.e. our
+ * third operand), the conditional operator returns a "void *" type.
+ * Here, within the sizeof(), we would then get:
+ * sizeof(*((void *)(...)) == sizeof(void) == 1
+ * - The equality comparison to "sizeof(int)" therefore depends on (x):
+ * sizeof(int) == sizeof(int) (x) was a constant expression
+ * sizeof(int) != sizeof(void) (x) was not a constant expression
+ */
+#define __is_constexpr(x) \
+ (sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8)))
+
+/*
+ * Similar to statically_true() but produces a constant expression
+ *
+ * To be used in conjunction with macros, such as BUILD_BUG_ON_ZERO(),
+ * which require their input to be a constant expression and for which
+ * statically_true() would otherwise fail.
+ *
+ * This is a trade-off: const_true() requires all its operands to be
+ * compile time constants. Else, it would always returns false even on
+ * the most trivial cases like:
+ *
+ * true || non_const_var
+ *
+ * On the opposite, statically_true() is able to fold more complex
+ * tautologies and will return true on expressions such as:
+ *
+ * !(non_const_var * 8 % 4)
+ *
+ * For the general case, statically_true() is better.
+ */
+#define const_true(x) __builtin_choose_expr(__is_constexpr(x), x, false)
+
+#endif
Hi,
kernel test robot noticed the following build errors:
[auto build test ERROR on next-20260120]
url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456
base: next-20260120
patch link: https://lore.kernel.org/r/20260121145731.3623-13-david.laight.linux%40gmail.com
patch subject: [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h
config: arm64-allmodconfig (https://download.01.org/0day-ci/archive/20260122/202601220951.7C4YG7hB-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601220951.7C4YG7hB-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601220951.7C4YG7hB-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
In file included from kernel/bounds.c:14:
In file included from include/linux/log2.h:12:
In file included from include/linux/bitops.h:28:
In file included from include/asm-generic/bitops/generic-non-atomic.h:7:
In file included from arch/arm64/include/asm/barrier.h:14:
>> arch/arm64/include/asm/alternative-macros.h:18:20: warning: 'unsigned' is not defined, evaluates to 0 [-Wundef]
18 | #if ARM64_NCAPS >= ARM64_CB_BIT
| ^
arch/arm64/include/asm/alternative-macros.h:16:22: note: expanded from macro 'ARM64_CB_BIT'
16 | #define ARM64_CB_BIT BIT(ARM64_CB_SHIFT)
| ^
include/linux/bits.h:94:18: note: expanded from macro 'BIT'
94 | #define BIT(nr) BIT_TYPE(unsigned long, nr)
| ^
include/linux/bits.h:88:4: note: expanded from macro 'BIT_TYPE'
88 | ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
| ^
In file included from kernel/bounds.c:14:
In file included from include/linux/log2.h:12:
In file included from include/linux/bitops.h:28:
In file included from include/asm-generic/bitops/generic-non-atomic.h:7:
In file included from arch/arm64/include/asm/barrier.h:14:
>> arch/arm64/include/asm/alternative-macros.h:18:20: error: token is not a valid binary operator in a preprocessor subexpression
18 | #if ARM64_NCAPS >= ARM64_CB_BIT
| ^~~~~~~~~~~~
arch/arm64/include/asm/alternative-macros.h:16:22: note: expanded from macro 'ARM64_CB_BIT'
16 | #define ARM64_CB_BIT BIT(ARM64_CB_SHIFT)
| ^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:94:18: note: expanded from macro 'BIT'
94 | #define BIT(nr) BIT_TYPE(unsigned long, nr)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:88:13: note: expanded from macro 'BIT_TYPE'
88 | ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
| ~~~~~~~~ ^
1 warning and 1 error generated.
make[3]: *** [scripts/Makefile.build:182: kernel/bounds.s] Error 1
make[3]: Target 'prepare' not remade because of errors.
make[2]: *** [Makefile:1330: prepare0] Error 2
make[2]: Target 'prepare' not remade because of errors.
make[1]: *** [Makefile:248: __sub-make] Error 2
make[1]: Target 'prepare' not remade because of errors.
make: *** [Makefile:248: __sub-make] Error 2
make: Target 'prepare' not remade because of errors.
vim +18 arch/arm64/include/asm/alternative-macros.h
4c0bd995d73ed8 Mark Rutland 2022-09-12 17
4c0bd995d73ed8 Mark Rutland 2022-09-12 @18 #if ARM64_NCAPS >= ARM64_CB_BIT
4c0bd995d73ed8 Mark Rutland 2022-09-12 19 #error "cpucaps have overflown ARM64_CB_BIT"
4c0bd995d73ed8 Mark Rutland 2022-09-12 20 #endif
7cda23da52ad79 Will Deacon 2020-06-30 21
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
On Thu, 22 Jan 2026 09:23:16 +0800 kernel test robot <lkp@intel.com> wrote: > Hi, > > kernel test robot noticed the following build errors: > > [auto build test ERROR on next-20260120] > > url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456 > base: next-20260120 > patch link: https://lore.kernel.org/r/20260121145731.3623-13-david.laight.linux%40gmail.com > patch subject: [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h > config: arm64-allmodconfig (https://download.01.org/0day-ci/archive/20260122/202601220951.7C4YG7hB-lkp@intel.com/config) > compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90) > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601220951.7C4YG7hB-lkp@intel.com/reproduce) > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > the same patch/commit), kindly add following tags > | Reported-by: kernel test robot <lkp@intel.com> > | Closes: https://lore.kernel.org/oe-kbuild-all/202601220951.7C4YG7hB-lkp@intel.com/ > > All error/warnings (new ones prefixed by >>): > > In file included from kernel/bounds.c:14: > In file included from include/linux/log2.h:12: > In file included from include/linux/bitops.h:28: > In file included from include/asm-generic/bitops/generic-non-atomic.h:7: > In file included from arch/arm64/include/asm/barrier.h:14: > >> arch/arm64/include/asm/alternative-macros.h:18:20: warning: 'unsigned' is not defined, evaluates to 0 [-Wundef] > 18 | #if ARM64_NCAPS >= ARM64_CB_BIT ... > > 4c0bd995d73ed8 Mark Rutland 2022-09-12 17 > 4c0bd995d73ed8 Mark Rutland 2022-09-12 @18 #if ARM64_NCAPS >= ARM64_CB_BIT > 4c0bd995d73ed8 Mark Rutland 2022-09-12 19 #error "cpucaps have overflown ARM64_CB_BIT" > 4c0bd995d73ed8 Mark Rutland 2022-09-12 20 #endif > 7cda23da52ad79 Will Deacon 2020-06-30 21 Unless I change BIT() back I'll change that to a static_assert(). David
Hi,
kernel test robot noticed the following build errors:
[auto build test ERROR on next-20260120]
url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456
base: next-20260120
patch link: https://lore.kernel.org/r/20260121145731.3623-13-david.laight.linux%40gmail.com
patch subject: [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h
config: arm-allnoconfig (https://download.01.org/0day-ci/archive/20260122/202601220832.NJbHlnXC-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 9b8addffa70cee5b2acc5454712d9cf78ce45710)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601220832.NJbHlnXC-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601220832.NJbHlnXC-lkp@intel.com/
All errors (new ones prefixed by >>):
163 | _SIG_SET_BINOP(sigandnsets, _sig_andn)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/signal.h:139:8: note: expanded from macro '_SIG_SET_BINOP'
139 | b3 = b->sig[3]; b2 = b->sig[2]; \
| ^ ~
arch/arm/include/asm/signal.h:17:2: note: array 'sig' declared here
17 | unsigned long sig[_NSIG_WORDS];
| ^
In file included from arch/arm/kernel/asm-offsets.c:14:
In file included from include/linux/mm.h:36:
In file included from include/linux/rcuwait.h:6:
In file included from include/linux/sched/signal.h:6:
include/linux/signal.h:163:1: warning: array index 2 is past the end of the array (that has type 'const unsigned long[2]') [-Warray-bounds]
163 | _SIG_SET_BINOP(sigandnsets, _sig_andn)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/signal.h:139:24: note: expanded from macro '_SIG_SET_BINOP'
139 | b3 = b->sig[3]; b2 = b->sig[2]; \
| ^ ~
arch/arm/include/asm/signal.h:17:2: note: array 'sig' declared here
17 | unsigned long sig[_NSIG_WORDS];
| ^
In file included from arch/arm/kernel/asm-offsets.c:14:
In file included from include/linux/mm.h:36:
In file included from include/linux/rcuwait.h:6:
In file included from include/linux/sched/signal.h:6:
include/linux/signal.h:163:1: warning: array index 3 is past the end of the array (that has type 'unsigned long[2]') [-Warray-bounds]
163 | _SIG_SET_BINOP(sigandnsets, _sig_andn)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/signal.h:140:3: note: expanded from macro '_SIG_SET_BINOP'
140 | r->sig[3] = op(a3, b3); \
| ^ ~
arch/arm/include/asm/signal.h:17:2: note: array 'sig' declared here
17 | unsigned long sig[_NSIG_WORDS];
| ^
In file included from arch/arm/kernel/asm-offsets.c:14:
In file included from include/linux/mm.h:36:
In file included from include/linux/rcuwait.h:6:
In file included from include/linux/sched/signal.h:6:
include/linux/signal.h:163:1: warning: array index 2 is past the end of the array (that has type 'unsigned long[2]') [-Warray-bounds]
163 | _SIG_SET_BINOP(sigandnsets, _sig_andn)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/signal.h:141:3: note: expanded from macro '_SIG_SET_BINOP'
141 | r->sig[2] = op(a2, b2); \
| ^ ~
arch/arm/include/asm/signal.h:17:2: note: array 'sig' declared here
17 | unsigned long sig[_NSIG_WORDS];
| ^
In file included from arch/arm/kernel/asm-offsets.c:14:
In file included from include/linux/mm.h:36:
In file included from include/linux/rcuwait.h:6:
In file included from include/linux/sched/signal.h:6:
include/linux/signal.h:187:1: warning: array index 3 is past the end of the array (that has type 'unsigned long[2]') [-Warray-bounds]
187 | _SIG_SET_OP(signotset, _sig_not)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/signal.h:174:27: note: expanded from macro '_SIG_SET_OP'
174 | case 4: set->sig[3] = op(set->sig[3]); \
| ^ ~
arch/arm/include/asm/signal.h:17:2: note: array 'sig' declared here
17 | unsigned long sig[_NSIG_WORDS];
| ^
In file included from arch/arm/kernel/asm-offsets.c:14:
In file included from include/linux/mm.h:36:
In file included from include/linux/rcuwait.h:6:
In file included from include/linux/sched/signal.h:6:
include/linux/signal.h:187:1: warning: array index 3 is past the end of the array (that has type 'unsigned long[2]') [-Warray-bounds]
187 | _SIG_SET_OP(signotset, _sig_not)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/signal.h:174:10: note: expanded from macro '_SIG_SET_OP'
174 | case 4: set->sig[3] = op(set->sig[3]); \
| ^ ~
arch/arm/include/asm/signal.h:17:2: note: array 'sig' declared here
17 | unsigned long sig[_NSIG_WORDS];
| ^
In file included from arch/arm/kernel/asm-offsets.c:14:
In file included from include/linux/mm.h:36:
In file included from include/linux/rcuwait.h:6:
In file included from include/linux/sched/signal.h:6:
include/linux/signal.h:187:1: warning: array index 2 is past the end of the array (that has type 'unsigned long[2]') [-Warray-bounds]
187 | _SIG_SET_OP(signotset, _sig_not)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/signal.h:175:20: note: expanded from macro '_SIG_SET_OP'
175 | set->sig[2] = op(set->sig[2]); \
| ^ ~
arch/arm/include/asm/signal.h:17:2: note: array 'sig' declared here
17 | unsigned long sig[_NSIG_WORDS];
| ^
In file included from arch/arm/kernel/asm-offsets.c:14:
In file included from include/linux/mm.h:36:
In file included from include/linux/rcuwait.h:6:
In file included from include/linux/sched/signal.h:6:
include/linux/signal.h:187:1: warning: array index 2 is past the end of the array (that has type 'unsigned long[2]') [-Warray-bounds]
187 | _SIG_SET_OP(signotset, _sig_not)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/signal.h:175:3: note: expanded from macro '_SIG_SET_OP'
175 | set->sig[2] = op(set->sig[2]); \
| ^ ~
arch/arm/include/asm/signal.h:17:2: note: array 'sig' declared here
17 | unsigned long sig[_NSIG_WORDS];
| ^
In file included from arch/arm/kernel/asm-offsets.c:14:
>> include/linux/mm.h:994:26: error: fields must have a constant size: 'variable length array in structure' extension will never be supported
994 | const vm_flags_t mask = BIT((__force int)bit);
| ^
include/linux/bits.h:94:18: note: expanded from macro 'BIT'
94 | #define BIT(nr) BIT_TYPE(unsigned long, nr)
| ^
include/linux/bits.h:88:17: note: expanded from macro 'BIT_TYPE'
88 | ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
| ^
include/linux/bits.h:82:24: note: expanded from macro 'BIT_INPUT_CHECK'
82 | sizeof(struct { char bit_number_too_big[-((nr) >= (width))];}), \
| ^
28 warnings and 16 errors generated.
make[3]: *** [scripts/Makefile.build:182: arch/arm/kernel/asm-offsets.s] Error 1
make[3]: Target 'prepare' not remade because of errors.
make[2]: *** [Makefile:1330: prepare0] Error 2
make[2]: Target 'prepare' not remade because of errors.
make[1]: *** [Makefile:248: __sub-make] Error 2
make[1]: Target 'prepare' not remade because of errors.
make: *** [Makefile:248: __sub-make] Error 2
make: Target 'prepare' not remade because of errors.
vim +994 include/linux/mm.h
bc292ab00f6c7a6 Suren Baghdasaryan 2023-01-26 990
568822502383acd Lorenzo Stoakes 2025-11-18 991 static inline bool __vma_flag_atomic_valid(struct vm_area_struct *vma,
2b6a3f061f11372 Lorenzo Stoakes 2025-11-25 992 vma_flag_t bit)
568822502383acd Lorenzo Stoakes 2025-11-18 993 {
2b6a3f061f11372 Lorenzo Stoakes 2025-11-25 @994 const vm_flags_t mask = BIT((__force int)bit);
568822502383acd Lorenzo Stoakes 2025-11-18 995
568822502383acd Lorenzo Stoakes 2025-11-18 996 /* Only specific flags are permitted */
568822502383acd Lorenzo Stoakes 2025-11-18 997 if (WARN_ON_ONCE(!(mask & VM_ATOMIC_SET_ALLOWED)))
568822502383acd Lorenzo Stoakes 2025-11-18 998 return false;
568822502383acd Lorenzo Stoakes 2025-11-18 999
568822502383acd Lorenzo Stoakes 2025-11-18 1000 return true;
568822502383acd Lorenzo Stoakes 2025-11-18 1001 }
568822502383acd Lorenzo Stoakes 2025-11-18 1002
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
On Wed, Jan 21, 2026 at 02:57:29PM +0000, david.laight.linux@gmail.com wrote:
> From: David Laight <david.laight.linux@gmail.com>
>
> The definition of BIT() was moved from linux/bits.h to vdso/bits.h to
> isolate the vdso from 'normal' kernel headers.
> BIT_ULL() was then moved to be defined in the same place for consistency.
>
> Since then linux/bits.h had gained BIT_Unn() and it really makes sense
> for BIT() and BIT_ULL() to be defined in the same place.
>
> Move BIT_ULL() and make code that include both headers use the definition
> of BIT() from linux/bits.h
> Add BIT_U128() for completness.
>
> This lets BIT() pick up the extra compile time checks for W=[1c] builds
> that detect errors like:
> long foo(void) { int x = 64; return BIT(x); }
> For which clang (silently) just generates a 'return' instruction.
>
> Note that nothing the the x86-64 build relies on the definition in
> vdso/bits.h, linux/bits.h is always included.
>
> Signed-off-by: David Laight <david.laight.linux@gmail.com>
> ---
> include/linux/bits.h | 7 ++++++-
> include/vdso/bits.h | 2 +-
> 2 files changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/bits.h b/include/linux/bits.h
> index 0f559038981d..3dd32b9eef35 100644
> --- a/include/linux/bits.h
> +++ b/include/linux/bits.h
> @@ -2,7 +2,6 @@
> #ifndef __LINUX_BITS_H
> #define __LINUX_BITS_H
>
> -#include <vdso/bits.h>
> #include <uapi/linux/bits.h>
>
> #define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG))
> @@ -89,10 +88,16 @@ int BIT_INPUT_CHECK_FAIL(void) __compiletime_error("Bit number out of range");
> ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
> #endif /* defined(__ASSEMBLY__) */
>
> +/* Prefer this definition of BIT() to the one in vdso/bits.h */
> +#undef BIT
> +#define __VDSO_BITS_H
This is ugly.
Why can't the vDSO code make use of those checks, too?
Or use _BITUL() from the UAPI in the vDSO and remove vdso/bits.h.
> +#define BIT(nr) BIT_TYPE(unsigned long, nr)
> +#define BIT_ULL(nr) BIT_TYPE(unsigned long long, 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)
> +#define BIT_U128(nr) BIT_TYPE(u128, nr)
>
> #if defined(__ASSEMBLY__)
>
> diff --git a/include/vdso/bits.h b/include/vdso/bits.h
> index 388b212088ea..a6ac1e6b637c 100644
> --- a/include/vdso/bits.h
> +++ b/include/vdso/bits.h
> @@ -4,7 +4,7 @@
> > #include <vdso/const.h>
>
> +/* Most code picks up BIT() from linux/bits.h */
> #define BIT(nr) (UL(1) << (nr))
> -#define BIT_ULL(nr) (ULL(1) << (nr))
>
> #endif /* __VDSO_BITS_H */
> --
> 2.39.5
>
On Wed, 21 Jan 2026 16:17:18 +0100
Thomas Weißschuh <thomas.weissschuh@linutronix.de> wrote:
> On Wed, Jan 21, 2026 at 02:57:29PM +0000, david.laight.linux@gmail.com wrote:
> > From: David Laight <david.laight.linux@gmail.com>
> >
> > The definition of BIT() was moved from linux/bits.h to vdso/bits.h to
> > isolate the vdso from 'normal' kernel headers.
> > BIT_ULL() was then moved to be defined in the same place for consistency.
> >
> > Since then linux/bits.h had gained BIT_Unn() and it really makes sense
> > for BIT() and BIT_ULL() to be defined in the same place.
> >
> > Move BIT_ULL() and make code that include both headers use the definition
> > of BIT() from linux/bits.h
> > Add BIT_U128() for completness.
> >
> > This lets BIT() pick up the extra compile time checks for W=[1c] builds
> > that detect errors like:
> > long foo(void) { int x = 64; return BIT(x); }
> > For which clang (silently) just generates a 'return' instruction.
> >
> > Note that nothing the the x86-64 build relies on the definition in
> > vdso/bits.h, linux/bits.h is always included.
> >
> > Signed-off-by: David Laight <david.laight.linux@gmail.com>
> > ---
> > include/linux/bits.h | 7 ++++++-
> > include/vdso/bits.h | 2 +-
> > 2 files changed, 7 insertions(+), 2 deletions(-)
> >
> > diff --git a/include/linux/bits.h b/include/linux/bits.h
> > index 0f559038981d..3dd32b9eef35 100644
> > --- a/include/linux/bits.h
> > +++ b/include/linux/bits.h
> > @@ -2,7 +2,6 @@
> > #ifndef __LINUX_BITS_H
> > #define __LINUX_BITS_H
> >
> > -#include <vdso/bits.h>
> > #include <uapi/linux/bits.h>
> >
> > #define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG))
> > @@ -89,10 +88,16 @@ int BIT_INPUT_CHECK_FAIL(void) __compiletime_error("Bit number out of range");
> > ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
> > #endif /* defined(__ASSEMBLY__) */
> >
> > +/* Prefer this definition of BIT() to the one in vdso/bits.h */
> > +#undef BIT
> > +#define __VDSO_BITS_H
>
> This is ugly.
It works :-)
I could have put an #ifndef BIT in vdso/bits.h instead.
> Why can't the vDSO code make use of those checks, too?
> Or use _BITUL() from the UAPI in the vDSO and remove vdso/bits.h.
I didn't actually find anything that just needed vdso/bits.h
linux/bits.h would get included - eg (IIRC) because of warn_on_once().
I'm not that sure why it got separated, it isn't as though it defines
anything that is code version specific.
David
>
> > +#define BIT(nr) BIT_TYPE(unsigned long, nr)
> > +#define BIT_ULL(nr) BIT_TYPE(unsigned long long, 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)
> > +#define BIT_U128(nr) BIT_TYPE(u128, nr)
> >
> > #if defined(__ASSEMBLY__)
> >
> > diff --git a/include/vdso/bits.h b/include/vdso/bits.h
> > index 388b212088ea..a6ac1e6b637c 100644
> > --- a/include/vdso/bits.h
> > +++ b/include/vdso/bits.h
> > @@ -4,7 +4,7 @@
> > > #include <vdso/const.h>
> >
> > +/* Most code picks up BIT() from linux/bits.h */
> > #define BIT(nr) (UL(1) << (nr))
> > -#define BIT_ULL(nr) (ULL(1) << (nr))
> >
> > #endif /* __VDSO_BITS_H */
> > --
> > 2.39.5
> >
On Wed, Jan 21, 2026 at 07:24:51PM +0000, David Laight wrote:
> On Wed, 21 Jan 2026 16:17:18 +0100
> Thomas Weißschuh <thomas.weissschuh@linutronix.de> wrote:
>
> > On Wed, Jan 21, 2026 at 02:57:29PM +0000, david.laight.linux@gmail.com wrote:
> > > From: David Laight <david.laight.linux@gmail.com>
> > >
> > > The definition of BIT() was moved from linux/bits.h to vdso/bits.h to
> > > isolate the vdso from 'normal' kernel headers.
> > > BIT_ULL() was then moved to be defined in the same place for consistency.
> > >
> > > Since then linux/bits.h had gained BIT_Unn() and it really makes sense
> > > for BIT() and BIT_ULL() to be defined in the same place.
> > >
> > > Move BIT_ULL() and make code that include both headers use the definition
> > > of BIT() from linux/bits.h
> > > Add BIT_U128() for completness.
> > >
> > > This lets BIT() pick up the extra compile time checks for W=[1c] builds
> > > that detect errors like:
> > > long foo(void) { int x = 64; return BIT(x); }
> > > For which clang (silently) just generates a 'return' instruction.
> > >
> > > Note that nothing the the x86-64 build relies on the definition in
> > > vdso/bits.h, linux/bits.h is always included.
> > >
> > > Signed-off-by: David Laight <david.laight.linux@gmail.com>
> > > ---
> > > include/linux/bits.h | 7 ++++++-
> > > include/vdso/bits.h | 2 +-
> > > 2 files changed, 7 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/include/linux/bits.h b/include/linux/bits.h
> > > index 0f559038981d..3dd32b9eef35 100644
> > > --- a/include/linux/bits.h
> > > +++ b/include/linux/bits.h
> > > @@ -2,7 +2,6 @@
> > > #ifndef __LINUX_BITS_H
> > > #define __LINUX_BITS_H
> > >
> > > -#include <vdso/bits.h>
> > > #include <uapi/linux/bits.h>
> > >
> > > #define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG))
> > > @@ -89,10 +88,16 @@ int BIT_INPUT_CHECK_FAIL(void) __compiletime_error("Bit number out of range");
> > > ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
> > > #endif /* defined(__ASSEMBLY__) */
> > >
> > > +/* Prefer this definition of BIT() to the one in vdso/bits.h */
> > > +#undef BIT
> > > +#define __VDSO_BITS_H
> >
> > This is ugly.
>
> It works :-)
> I could have put an #ifndef BIT in vdso/bits.h instead.
The #ifndef in vdso/bits.h is not much better IMO.
Given that there a multiple nicer options why not use on of those?
> > Why can't the vDSO code make use of those checks, too?
> > Or use _BITUL() from the UAPI in the vDSO and remove vdso/bits.h.
>
> I didn't actually find anything that just needed vdso/bits.h
> linux/bits.h would get included - eg (IIRC) because of warn_on_once().
That is a bug. The vdso code should only include the vdso/ namespace.
Right now the inclusions are all over the place. I'd like to clean that
up at some point.
> I'm not that sure why it got separated, it isn't as though it defines
> anything that is code version specific.
I don't understand "code version specific".
There are various issues with including normal kernel headers from the vDSO.
Symbols defined in terms of kconfig options, like BITS_PER_LONG using
CONFIG_64BIT are wrong in a compat vDSO.
> > > +#define BIT(nr) BIT_TYPE(unsigned long, nr)
> > > +#define BIT_ULL(nr) BIT_TYPE(unsigned long long, 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)
> > > +#define BIT_U128(nr) BIT_TYPE(u128, nr)
> > >
> > > #if defined(__ASSEMBLY__)
> > >
> > > diff --git a/include/vdso/bits.h b/include/vdso/bits.h
> > > index 388b212088ea..a6ac1e6b637c 100644
> > > --- a/include/vdso/bits.h
> > > +++ b/include/vdso/bits.h
> > > @@ -4,7 +4,7 @@
> > > > #include <vdso/const.h>
> > >
> > > +/* Most code picks up BIT() from linux/bits.h */
> > > #define BIT(nr) (UL(1) << (nr))
> > > -#define BIT_ULL(nr) (ULL(1) << (nr))
> > >
> > > #endif /* __VDSO_BITS_H */
> > > --
> > > 2.39.5
> > >
>
© 2016 - 2026 Red Hat, Inc.