]>
Commit | Line | Data |
---|---|---|
f9c15319 GKH |
1 | From 6147e136ff5071609b54f18982dea87706288e21 Mon Sep 17 00:00:00 2001 |
2 | From: Arnd Bergmann <arnd@arndb.de> | |
3 | Date: Fri, 5 Apr 2019 18:38:53 -0700 | |
4 | Subject: include/linux/bitrev.h: fix constant bitrev | |
5 | ||
6 | From: Arnd Bergmann <arnd@arndb.de> | |
7 | ||
8 | commit 6147e136ff5071609b54f18982dea87706288e21 upstream. | |
9 | ||
10 | clang points out with hundreds of warnings that the bitrev macros have a | |
11 | problem with constant input: | |
12 | ||
13 | drivers/hwmon/sht15.c:187:11: error: variable '__x' is uninitialized when used within its own initialization | |
14 | [-Werror,-Wuninitialized] | |
15 | u8 crc = bitrev8(data->val_status & 0x0F); | |
16 | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
17 | include/linux/bitrev.h:102:21: note: expanded from macro 'bitrev8' | |
18 | __constant_bitrev8(__x) : \ | |
19 | ~~~~~~~~~~~~~~~~~~~^~~~ | |
20 | include/linux/bitrev.h:67:11: note: expanded from macro '__constant_bitrev8' | |
21 | u8 __x = x; \ | |
22 | ~~~ ^ | |
23 | ||
24 | Both the bitrev and the __constant_bitrev macros use an internal | |
25 | variable named __x, which goes horribly wrong when passing one to the | |
26 | other. | |
27 | ||
28 | The obvious fix is to rename one of the variables, so this adds an extra | |
29 | '_'. | |
30 | ||
31 | It seems we got away with this because | |
32 | ||
33 | - there are only a few drivers using bitrev macros | |
34 | ||
35 | - usually there are no constant arguments to those | |
36 | ||
37 | - when they are constant, they tend to be either 0 or (unsigned)-1 | |
38 | (drivers/isdn/i4l/isdnhdlc.o, drivers/iio/amplifiers/ad8366.c) and | |
39 | give the correct result by pure chance. | |
40 | ||
41 | In fact, the only driver that I could find that gets different results | |
42 | with this is drivers/net/wan/slic_ds26522.c, which in turn is a driver | |
43 | for fairly rare hardware (adding the maintainer to Cc for testing). | |
44 | ||
45 | Link: http://lkml.kernel.org/r/20190322140503.123580-1-arnd@arndb.de | |
46 | Fixes: 556d2f055bf6 ("ARM: 8187/1: add CONFIG_HAVE_ARCH_BITREVERSE to support rbit instruction") | |
47 | Signed-off-by: Arnd Bergmann <arnd@arndb.de> | |
48 | Reviewed-by: Nick Desaulniers <ndesaulniers@google.com> | |
49 | Cc: Zhao Qiang <qiang.zhao@nxp.com> | |
50 | Cc: Yalin Wang <yalin.wang@sonymobile.com> | |
51 | Cc: <stable@vger.kernel.org> | |
52 | Signed-off-by: Andrew Morton <akpm@linux-foundation.org> | |
53 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
54 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
55 | ||
56 | --- | |
57 | include/linux/bitrev.h | 36 ++++++++++++++++++------------------ | |
58 | 1 file changed, 18 insertions(+), 18 deletions(-) | |
59 | ||
60 | --- a/include/linux/bitrev.h | |
61 | +++ b/include/linux/bitrev.h | |
62 | @@ -31,32 +31,32 @@ static inline u32 __bitrev32(u32 x) | |
63 | ||
64 | #define __constant_bitrev32(x) \ | |
65 | ({ \ | |
66 | - u32 __x = x; \ | |
67 | - __x = (__x >> 16) | (__x << 16); \ | |
68 | - __x = ((__x & (u32)0xFF00FF00UL) >> 8) | ((__x & (u32)0x00FF00FFUL) << 8); \ | |
69 | - __x = ((__x & (u32)0xF0F0F0F0UL) >> 4) | ((__x & (u32)0x0F0F0F0FUL) << 4); \ | |
70 | - __x = ((__x & (u32)0xCCCCCCCCUL) >> 2) | ((__x & (u32)0x33333333UL) << 2); \ | |
71 | - __x = ((__x & (u32)0xAAAAAAAAUL) >> 1) | ((__x & (u32)0x55555555UL) << 1); \ | |
72 | - __x; \ | |
73 | + u32 ___x = x; \ | |
74 | + ___x = (___x >> 16) | (___x << 16); \ | |
75 | + ___x = ((___x & (u32)0xFF00FF00UL) >> 8) | ((___x & (u32)0x00FF00FFUL) << 8); \ | |
76 | + ___x = ((___x & (u32)0xF0F0F0F0UL) >> 4) | ((___x & (u32)0x0F0F0F0FUL) << 4); \ | |
77 | + ___x = ((___x & (u32)0xCCCCCCCCUL) >> 2) | ((___x & (u32)0x33333333UL) << 2); \ | |
78 | + ___x = ((___x & (u32)0xAAAAAAAAUL) >> 1) | ((___x & (u32)0x55555555UL) << 1); \ | |
79 | + ___x; \ | |
80 | }) | |
81 | ||
82 | #define __constant_bitrev16(x) \ | |
83 | ({ \ | |
84 | - u16 __x = x; \ | |
85 | - __x = (__x >> 8) | (__x << 8); \ | |
86 | - __x = ((__x & (u16)0xF0F0U) >> 4) | ((__x & (u16)0x0F0FU) << 4); \ | |
87 | - __x = ((__x & (u16)0xCCCCU) >> 2) | ((__x & (u16)0x3333U) << 2); \ | |
88 | - __x = ((__x & (u16)0xAAAAU) >> 1) | ((__x & (u16)0x5555U) << 1); \ | |
89 | - __x; \ | |
90 | + u16 ___x = x; \ | |
91 | + ___x = (___x >> 8) | (___x << 8); \ | |
92 | + ___x = ((___x & (u16)0xF0F0U) >> 4) | ((___x & (u16)0x0F0FU) << 4); \ | |
93 | + ___x = ((___x & (u16)0xCCCCU) >> 2) | ((___x & (u16)0x3333U) << 2); \ | |
94 | + ___x = ((___x & (u16)0xAAAAU) >> 1) | ((___x & (u16)0x5555U) << 1); \ | |
95 | + ___x; \ | |
96 | }) | |
97 | ||
98 | #define __constant_bitrev8(x) \ | |
99 | ({ \ | |
100 | - u8 __x = x; \ | |
101 | - __x = (__x >> 4) | (__x << 4); \ | |
102 | - __x = ((__x & (u8)0xCCU) >> 2) | ((__x & (u8)0x33U) << 2); \ | |
103 | - __x = ((__x & (u8)0xAAU) >> 1) | ((__x & (u8)0x55U) << 1); \ | |
104 | - __x; \ | |
105 | + u8 ___x = x; \ | |
106 | + ___x = (___x >> 4) | (___x << 4); \ | |
107 | + ___x = ((___x & (u8)0xCCU) >> 2) | ((___x & (u8)0x33U) << 2); \ | |
108 | + ___x = ((___x & (u8)0xAAU) >> 1) | ((___x & (u8)0x55U) << 1); \ | |
109 | + ___x; \ | |
110 | }) | |
111 | ||
112 | #define bitrev32(x) \ |