The newly introduced GENMASK_TYPE() macro can also be used to generate
the pre-existing non-asm GENMASK*() variants.
Apply GENMASK_TYPE() to GENMASK(), GENMASK_ULL() and GENMASK_U128().
Signed-off-by: Vincent Mailhol <[email protected]>
Signed-off-by: Yury Norov (NVIDIA) <[email protected]>
In an upcoming change, the non-asm GENMASK*() will all be unified to
depend on GENMASK_TYPE() which indirectly depend on sizeof(), something
not available in asm.
Instead of adding further complexity to GENMASK_TYPE() to make it work
for both asm and non asm, just split the definition of the two variants.
Signed-off-by: Vincent Mailhol <[email protected]>
Reviewed-by: Lucas De Marchi <[email protected]>
Signed-off-by: Yury Norov (NVIDIA) <[email protected]>
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 <[email protected]>
Signed-off-by: Lucas De Marchi <[email protected]>
Acked-by: Jani Nikula <[email protected]>
Signed-off-by: Vincent Mailhol <[email protected]>
Reviewed-by: Andy Shevchenko <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
This is a preparation for the upcoming GENMASK_U*() and BIT_U*()
changes. After introducing those new macros, there will be a lot of
scrolling between the #if, #else and #endif.
Add a comment to the #else and #endif preprocessor macros to help keep
track of which context we are in. Also, add new lines to better
visually separate the non-asm and asm sections.
Signed-off-by: Vincent Mailhol <[email protected]>
Reviewed-by: Andy Shevchenko <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
"int" was misspelled as "init" the code comments in the bits.h and
const.h files. Fix the typo.
CC: Andy Shevchenko <[email protected]>
Signed-off-by: Vincent Mailhol <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
This adds GENMASK_U128() and __GENMASK_U128() macros using __BITS_PER_U128
and __int128 data types. These macros will be used in providing support for
generating 128 bit masks.
The macros wouldn't work in all assembler flavors for reasons described
in the comments on top of declarations. Enforce it for more by adding
!__ASSEMBLY__ guard.
Cc: Yury Norov <[email protected]>
Cc: Rasmus Villemoes <[email protected]>
Cc: Arnd Bergmann <[email protected]>>
Cc: [email protected]
Cc: [email protected]
Reviewed-by: Arnd Bergmann <[email protected]>
Signed-off-by: Anshuman Khandual <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Move __GENMASK and __GENMASK_ULL from include/ to include/uapi/ so that they can
be used to define masks in userspace API headers. Compared to what is already
in include/linux/bits.h, the definitions need to use the uglified versions of
UL(), ULL(), BITS_PER_LONG and BITS_PER_LONG_LONG (which did not even exist),
but otherwise expand to the same content.
Signed-off-by: Paolo Bonzini <[email protected]>
The minimization done in 3945ff37d2 ("linux/bits.h: Extract common header
for vDSO") was required to isolate the VDSO build from the larger kernel
header impact.
The split added some inconsistency since BIT() and BIT_ULL() are now
defined in the different files which confuses unprepared reader.
Move BIT_ULL() to vdso/bits.h. No functional change.
Signed-off-by: Andy Shevchenko <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
I realize that we fairly recently raised it to 4.8, but the fact is, 4.9
is a much better minimum version to target.
We have a number of workarounds for actual bugs in pre-4.9 gcc versions
(including things like internal compiler errors on ARM), but we also
have some syntactic workarounds for lacking features.
In particular, raising the minimum to 4.9 means that we can now just
assume _Generic() exists, which is likely the much better replacement
for a lot of very convoluted built-time magic with conditionals on
sizeof and/or __builtin_choose_expr() with same_type() etc.
Using _Generic also means that you will need to have a very recent
version of 'sparse', but thats easy to build yourself, and much less of
a hassle than some old gcc version can be.
The latest (in a long string) of reasons for minimum compiler version
upgrades was commit 5435f73d5c ("efi/x86: Fix build with gcc 4").
Ard points out that RHEL 7 uses gcc-4.8, but the people who stay back on
old RHEL versions persumably also don't build their own kernels anyway.
And maybe they should cross-built or just have a little side affair with
a newer compiler?
Acked-by: Ard Biesheuvel <[email protected]>
Acked-by: Peter Zijlstra <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
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
aa4c0c9091 ("net: stmmac: Fix misuses of GENMASK macro") and commit
9bdd7bb3a8 ("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 95b980d62d ("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 <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Reviewed-by: Masahiro Yamada <[email protected]>
Reviewed-by: Kees Cook <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Geert Uytterhoeven <[email protected]>
Cc: Haren Myneni <[email protected]>
Cc: Joe Perches <[email protected]>
Cc: Johannes Berg <[email protected]>
Cc: lkml <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Linus Torvalds <[email protected]>
The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.
Split bits.h into linux and common headers to make the latter suitable
for inclusion in the vDSO library.
Signed-off-by: Vincenzo Frascino <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
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/[email protected]
Signed-off-by: Masahiro Yamada <[email protected]>
Cc: Catalin Marinas <[email protected]>
Cc: Christian Borntraeger <[email protected]>
Cc: Heiko Carstens <[email protected]>
Cc: Vasily Gorbik <[email protected]>
Cc: Vineet Gupta <[email protected]>
Cc: Will Deacon <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>