Refreshed patches for generic/backport-6.18 by running make target/linux/refresh Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com> Link: https://github.com/openwrt/openwrt/pull/21078 Signed-off-by: Robert Marko <robimarko@gmail.com>
104 lines
3.7 KiB
Diff
104 lines
3.7 KiB
Diff
From 2a6c045640c38a407a39cd40c3c4d8dd2fd89aa8 Mon Sep 17 00:00:00 2001
|
|
From: Geert Uytterhoeven <geert+renesas@glider.be>
|
|
Date: Thu, 6 Nov 2025 14:34:00 +0100
|
|
Subject: [PATCH 1/2] bitfield: Add less-checking __FIELD_{GET,PREP}()
|
|
|
|
The BUILD_BUG_ON_MSG() check against "~0ull" works only with "unsigned
|
|
(long) long" _mask types. For constant masks, that condition is usually
|
|
met, as GENMASK() yields an UL value. The few places where the
|
|
constant mask is stored in an intermediate variable were fixed by
|
|
changing the variable type to u64 (see e.g. [1] and [2]).
|
|
|
|
However, for non-constant masks, smaller unsigned types should be valid,
|
|
too, but currently lead to "result of comparison of constant
|
|
18446744073709551615 with expression of type ... is always
|
|
false"-warnings with clang and W=1.
|
|
|
|
Hence refactor the __BF_FIELD_CHECK() helper, and factor out
|
|
__FIELD_{GET,PREP}(). The later lack the single problematic check, but
|
|
are otherwise identical to FIELD_{GET,PREP}(), and are intended to be
|
|
used in the fully non-const variants later.
|
|
|
|
[1] commit 5c667d5a5a3ec166 ("clk: sp7021: Adjust width of _m in
|
|
HWM_FIELD_PREP()")
|
|
[2] commit cfd6fb45cfaf46fa ("crypto: ccree - avoid out-of-range
|
|
warnings from clang")
|
|
|
|
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
|
|
Link: https://git.kernel.org/torvalds/c/5c667d5a5a3ec166 [1]
|
|
Signed-off-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
|
|
---
|
|
include/linux/bitfield.h | 36 ++++++++++++++++++++++++++++--------
|
|
1 file changed, 28 insertions(+), 8 deletions(-)
|
|
|
|
--- a/include/linux/bitfield.h
|
|
+++ b/include/linux/bitfield.h
|
|
@@ -60,7 +60,7 @@
|
|
|
|
#define __bf_cast_unsigned(type, x) ((__unsigned_scalar_typeof(type))(x))
|
|
|
|
-#define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \
|
|
+#define __BF_FIELD_CHECK_MASK(_mask, _val, _pfx) \
|
|
({ \
|
|
BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \
|
|
_pfx "mask is not constant"); \
|
|
@@ -69,13 +69,33 @@
|
|
~((_mask) >> __bf_shf(_mask)) & \
|
|
(0 + (_val)) : 0, \
|
|
_pfx "value too large for the field"); \
|
|
- BUILD_BUG_ON_MSG(__bf_cast_unsigned(_mask, _mask) > \
|
|
- __bf_cast_unsigned(_reg, ~0ull), \
|
|
- _pfx "type of reg too small for mask"); \
|
|
__BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \
|
|
(1ULL << __bf_shf(_mask))); \
|
|
})
|
|
|
|
+#define __BF_FIELD_CHECK_REG(mask, reg, pfx) \
|
|
+ BUILD_BUG_ON_MSG(__bf_cast_unsigned(mask, mask) > \
|
|
+ __bf_cast_unsigned(reg, ~0ull), \
|
|
+ pfx "type of reg too small for mask")
|
|
+
|
|
+#define __BF_FIELD_CHECK(mask, reg, val, pfx) \
|
|
+ ({ \
|
|
+ __BF_FIELD_CHECK_MASK(mask, val, pfx); \
|
|
+ __BF_FIELD_CHECK_REG(mask, reg, pfx); \
|
|
+ })
|
|
+
|
|
+#define __FIELD_PREP(mask, val, pfx) \
|
|
+ ({ \
|
|
+ __BF_FIELD_CHECK_MASK(mask, val, pfx); \
|
|
+ ((typeof(mask))(val) << __bf_shf(mask)) & (mask); \
|
|
+ })
|
|
+
|
|
+#define __FIELD_GET(mask, reg, pfx) \
|
|
+ ({ \
|
|
+ __BF_FIELD_CHECK_MASK(mask, 0U, pfx); \
|
|
+ (typeof(mask))(((reg) & (mask)) >> __bf_shf(mask)); \
|
|
+ })
|
|
+
|
|
/**
|
|
* FIELD_MAX() - produce the maximum value representable by a field
|
|
* @_mask: shifted mask defining the field's length and position
|
|
@@ -112,8 +132,8 @@
|
|
*/
|
|
#define FIELD_PREP(_mask, _val) \
|
|
({ \
|
|
- __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \
|
|
- ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \
|
|
+ __BF_FIELD_CHECK_REG(_mask, 0ULL, "FIELD_PREP: "); \
|
|
+ __FIELD_PREP(_mask, _val, "FIELD_PREP: "); \
|
|
})
|
|
|
|
#define __BF_CHECK_POW2(n) BUILD_BUG_ON_ZERO(((n) & ((n) - 1)) != 0)
|
|
@@ -152,8 +172,8 @@
|
|
*/
|
|
#define FIELD_GET(_mask, _reg) \
|
|
({ \
|
|
- __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \
|
|
- (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \
|
|
+ __BF_FIELD_CHECK_REG(_mask, _reg, "FIELD_GET: "); \
|
|
+ __FIELD_GET(_mask, _reg, "FIELD_GET: "); \
|
|
})
|
|
|
|
/**
|