diff options
author | H. Peter Anvin <hpa@zytor.com> | 2013-02-11 19:27:28 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2013-02-11 20:26:51 -0500 |
commit | b390784dc1649f6e6c5e66e5f53c21e715ccf39b (patch) | |
tree | d8c68a501fcb84f3b69820b0558d936a331c1aac | |
parent | 136867f517cbc3f8a91f035677911a6b503c3323 (diff) |
x86, mm: Use a bitfield to mask nuisance get_user() warnings
Even though it is never executed, gcc wants to warn for casting from
a large integer to a pointer. Furthermore, using a variable with
__typeof__() doesn't work because __typeof__ retains storage
specifiers (const, restrict, volatile).
However, we can declare a bitfield using sizeof(), which is legal
because sizeof() is a constant expression. This quiets the warning,
although the code generated isn't 100% identical from the baseline
before 96477b4 x86-32: Add support for 64bit get_user():
[x86-mb is baseline, x86-mm is this commit]
text data bss filename
113716147 15858380 35037184 tip.x86-mb/o.i386-allconfig/vmlinux
113716145 15858380 35037184 tip.x86-mm/o.i386-allconfig/vmlinux
12989837 3597944 12255232 tip.x86-mb/o.i386-modconfig/vmlinux
12989831 3597944 12255232 tip.x86-mm/o.i386-modconfig/vmlinux
1462784 237608 1401988 tip.x86-mb/o.i386-noconfig/vmlinux
1462837 237608 1401964 tip.x86-mm/o.i386-noconfig/vmlinux
7938994 553688 7639040 tip.x86-mb/o.i386-pae/vmlinux
7943136 557784 7639040 tip.x86-mm/o.i386-pae/vmlinux
7186126 510572 6574080 tip.x86-mb/o.i386/vmlinux
7186124 510572 6574080 tip.x86-mm/o.i386/vmlinux
103747269 33578856 65888256 tip.x86-mb/o.x86_64-allconfig/vmlinux
103746949 33578856 65888256 tip.x86-mm/o.x86_64-allconfig/vmlinux
12116695 11035832 20160512 tip.x86-mb/o.x86_64-modconfig/vmlinux
12116567 11035832 20160512 tip.x86-mm/o.x86_64-modconfig/vmlinux
1700790 380524 511808 tip.x86-mb/o.x86_64-noconfig/vmlinux
1700790 380524 511808 tip.x86-mm/o.x86_64-noconfig/vmlinux
12413612 1133376 1101824 tip.x86-mb/o.x86_64/vmlinux
12413484 1133376 1101824 tip.x86-mm/o.x86_64/vmlinux
Cc: Jamie Lokier <jamie@shareable.org>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: http://lkml.kernel.org/r/20130209110031.GA17833@n2100.arm.linux.org.uk
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r-- | arch/x86/include/asm/uaccess.h | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 1e963267d44e..a8d12653f304 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h | |||
@@ -168,31 +168,29 @@ do { \ | |||
168 | #define get_user(x, ptr) \ | 168 | #define get_user(x, ptr) \ |
169 | ({ \ | 169 | ({ \ |
170 | int __ret_gu; \ | 170 | int __ret_gu; \ |
171 | unsigned long __val_gu; \ | 171 | struct { \ |
172 | unsigned long long __val_gu8; \ | 172 | unsigned long long __val_n : 8*sizeof(*(ptr)); \ |
173 | } __val_gu; \ | ||
173 | __chk_user_ptr(ptr); \ | 174 | __chk_user_ptr(ptr); \ |
174 | might_fault(); \ | 175 | might_fault(); \ |
175 | switch (sizeof(*(ptr))) { \ | 176 | switch (sizeof(*(ptr))) { \ |
176 | case 1: \ | 177 | case 1: \ |
177 | __get_user_x(1, __ret_gu, __val_gu, ptr); \ | 178 | __get_user_x(1, __ret_gu, __val_gu.__val_n, ptr); \ |
178 | break; \ | 179 | break; \ |
179 | case 2: \ | 180 | case 2: \ |
180 | __get_user_x(2, __ret_gu, __val_gu, ptr); \ | 181 | __get_user_x(2, __ret_gu, __val_gu.__val_n, ptr); \ |
181 | break; \ | 182 | break; \ |
182 | case 4: \ | 183 | case 4: \ |
183 | __get_user_x(4, __ret_gu, __val_gu, ptr); \ | 184 | __get_user_x(4, __ret_gu, __val_gu.__val_n, ptr); \ |
184 | break; \ | 185 | break; \ |
185 | case 8: \ | 186 | case 8: \ |
186 | __get_user_8(__ret_gu, __val_gu8, ptr); \ | 187 | __get_user_8(__ret_gu, __val_gu.__val_n, ptr); \ |
187 | break; \ | 188 | break; \ |
188 | default: \ | 189 | default: \ |
189 | __get_user_x(X, __ret_gu, __val_gu, ptr); \ | 190 | __get_user_x(X, __ret_gu, __val_gu.__val_n, ptr); \ |
190 | break; \ | 191 | break; \ |
191 | } \ | 192 | } \ |
192 | if (sizeof(*(ptr)) == 8) \ | 193 | (x) = (__typeof__(*(ptr)))__val_gu.__val_n; \ |
193 | (x) = (__typeof__(*(ptr)))__val_gu8; \ | ||
194 | else \ | ||
195 | (x) = (__typeof__(*(ptr)))__val_gu; \ | ||
196 | __ret_gu; \ | 194 | __ret_gu; \ |
197 | }) | 195 | }) |
198 | 196 | ||