Annotation of /trunk/kernel-alx/patches-4.4/0129-4.4.30-all-fixes.patch
Parent Directory | Revision Log
Revision 2865 -
(hide annotations)
(download)
Mon Mar 27 13:49:09 2017 UTC (7 years, 2 months ago) by niro
File size: 13181 byte(s)
Mon Mar 27 13:49:09 2017 UTC (7 years, 2 months ago) by niro
File size: 13181 byte(s)
linux-4.4.30
1 | niro | 2865 | diff --git a/Documentation/x86/exception-tables.txt b/Documentation/x86/exception-tables.txt |
2 | index e396bcd8d830..32901aa36f0a 100644 | ||
3 | --- a/Documentation/x86/exception-tables.txt | ||
4 | +++ b/Documentation/x86/exception-tables.txt | ||
5 | @@ -290,38 +290,3 @@ Due to the way that the exception table is built and needs to be ordered, | ||
6 | only use exceptions for code in the .text section. Any other section | ||
7 | will cause the exception table to not be sorted correctly, and the | ||
8 | exceptions will fail. | ||
9 | - | ||
10 | -Things changed when 64-bit support was added to x86 Linux. Rather than | ||
11 | -double the size of the exception table by expanding the two entries | ||
12 | -from 32-bits to 64 bits, a clever trick was used to store addresses | ||
13 | -as relative offsets from the table itself. The assembly code changed | ||
14 | -from: | ||
15 | - .long 1b,3b | ||
16 | -to: | ||
17 | - .long (from) - . | ||
18 | - .long (to) - . | ||
19 | - | ||
20 | -and the C-code that uses these values converts back to absolute addresses | ||
21 | -like this: | ||
22 | - | ||
23 | - ex_insn_addr(const struct exception_table_entry *x) | ||
24 | - { | ||
25 | - return (unsigned long)&x->insn + x->insn; | ||
26 | - } | ||
27 | - | ||
28 | -In v4.6 the exception table entry was expanded with a new field "handler". | ||
29 | -This is also 32-bits wide and contains a third relative function | ||
30 | -pointer which points to one of: | ||
31 | - | ||
32 | -1) int ex_handler_default(const struct exception_table_entry *fixup) | ||
33 | - This is legacy case that just jumps to the fixup code | ||
34 | -2) int ex_handler_fault(const struct exception_table_entry *fixup) | ||
35 | - This case provides the fault number of the trap that occurred at | ||
36 | - entry->insn. It is used to distinguish page faults from machine | ||
37 | - check. | ||
38 | -3) int ex_handler_ext(const struct exception_table_entry *fixup) | ||
39 | - This case is used for uaccess_err ... we need to set a flag | ||
40 | - in the task structure. Before the handler functions existed this | ||
41 | - case was handled by adding a large offset to the fixup to tag | ||
42 | - it as special. | ||
43 | -More functions can easily be added. | ||
44 | diff --git a/Makefile b/Makefile | ||
45 | index 19d7d9f68e35..98239d56924c 100644 | ||
46 | --- a/Makefile | ||
47 | +++ b/Makefile | ||
48 | @@ -1,6 +1,6 @@ | ||
49 | VERSION = 4 | ||
50 | PATCHLEVEL = 4 | ||
51 | -SUBLEVEL = 29 | ||
52 | +SUBLEVEL = 30 | ||
53 | EXTRAVERSION = | ||
54 | NAME = Blurry Fish Butt | ||
55 | |||
56 | diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h | ||
57 | index f5063b6659eb..189679aba703 100644 | ||
58 | --- a/arch/x86/include/asm/asm.h | ||
59 | +++ b/arch/x86/include/asm/asm.h | ||
60 | @@ -44,22 +44,19 @@ | ||
61 | |||
62 | /* Exception table entry */ | ||
63 | #ifdef __ASSEMBLY__ | ||
64 | -# define _ASM_EXTABLE_HANDLE(from, to, handler) \ | ||
65 | +# define _ASM_EXTABLE(from,to) \ | ||
66 | .pushsection "__ex_table","a" ; \ | ||
67 | - .balign 4 ; \ | ||
68 | + .balign 8 ; \ | ||
69 | .long (from) - . ; \ | ||
70 | .long (to) - . ; \ | ||
71 | - .long (handler) - . ; \ | ||
72 | .popsection | ||
73 | |||
74 | -# define _ASM_EXTABLE(from, to) \ | ||
75 | - _ASM_EXTABLE_HANDLE(from, to, ex_handler_default) | ||
76 | - | ||
77 | -# define _ASM_EXTABLE_FAULT(from, to) \ | ||
78 | - _ASM_EXTABLE_HANDLE(from, to, ex_handler_fault) | ||
79 | - | ||
80 | -# define _ASM_EXTABLE_EX(from, to) \ | ||
81 | - _ASM_EXTABLE_HANDLE(from, to, ex_handler_ext) | ||
82 | +# define _ASM_EXTABLE_EX(from,to) \ | ||
83 | + .pushsection "__ex_table","a" ; \ | ||
84 | + .balign 8 ; \ | ||
85 | + .long (from) - . ; \ | ||
86 | + .long (to) - . + 0x7ffffff0 ; \ | ||
87 | + .popsection | ||
88 | |||
89 | # define _ASM_NOKPROBE(entry) \ | ||
90 | .pushsection "_kprobe_blacklist","aw" ; \ | ||
91 | @@ -92,24 +89,19 @@ | ||
92 | .endm | ||
93 | |||
94 | #else | ||
95 | -# define _EXPAND_EXTABLE_HANDLE(x) #x | ||
96 | -# define _ASM_EXTABLE_HANDLE(from, to, handler) \ | ||
97 | +# define _ASM_EXTABLE(from,to) \ | ||
98 | " .pushsection \"__ex_table\",\"a\"\n" \ | ||
99 | - " .balign 4\n" \ | ||
100 | + " .balign 8\n" \ | ||
101 | " .long (" #from ") - .\n" \ | ||
102 | " .long (" #to ") - .\n" \ | ||
103 | - " .long (" _EXPAND_EXTABLE_HANDLE(handler) ") - .\n" \ | ||
104 | " .popsection\n" | ||
105 | |||
106 | -# define _ASM_EXTABLE(from, to) \ | ||
107 | - _ASM_EXTABLE_HANDLE(from, to, ex_handler_default) | ||
108 | - | ||
109 | -# define _ASM_EXTABLE_FAULT(from, to) \ | ||
110 | - _ASM_EXTABLE_HANDLE(from, to, ex_handler_fault) | ||
111 | - | ||
112 | -# define _ASM_EXTABLE_EX(from, to) \ | ||
113 | - _ASM_EXTABLE_HANDLE(from, to, ex_handler_ext) | ||
114 | - | ||
115 | +# define _ASM_EXTABLE_EX(from,to) \ | ||
116 | + " .pushsection \"__ex_table\",\"a\"\n" \ | ||
117 | + " .balign 8\n" \ | ||
118 | + " .long (" #from ") - .\n" \ | ||
119 | + " .long (" #to ") - . + 0x7ffffff0\n" \ | ||
120 | + " .popsection\n" | ||
121 | /* For C file, we already have NOKPROBE_SYMBOL macro */ | ||
122 | #endif | ||
123 | |||
124 | diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h | ||
125 | index 3794c7331cfc..09b1b0ab94b7 100644 | ||
126 | --- a/arch/x86/include/asm/uaccess.h | ||
127 | +++ b/arch/x86/include/asm/uaccess.h | ||
128 | @@ -90,11 +90,12 @@ static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, un | ||
129 | likely(!__range_not_ok(addr, size, user_addr_max())) | ||
130 | |||
131 | /* | ||
132 | - * The exception table consists of triples of addresses relative to the | ||
133 | - * exception table entry itself. The first address is of an instruction | ||
134 | - * that is allowed to fault, the second is the target at which the program | ||
135 | - * should continue. The third is a handler function to deal with the fault | ||
136 | - * caused by the instruction in the first field. | ||
137 | + * The exception table consists of pairs of addresses relative to the | ||
138 | + * exception table enty itself: the first is the address of an | ||
139 | + * instruction that is allowed to fault, and the second is the address | ||
140 | + * at which the program should continue. No registers are modified, | ||
141 | + * so it is entirely up to the continuation code to figure out what to | ||
142 | + * do. | ||
143 | * | ||
144 | * All the routines below use bits of fixup code that are out of line | ||
145 | * with the main instruction path. This means when everything is well, | ||
146 | @@ -103,14 +104,13 @@ static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, un | ||
147 | */ | ||
148 | |||
149 | struct exception_table_entry { | ||
150 | - int insn, fixup, handler; | ||
151 | + int insn, fixup; | ||
152 | }; | ||
153 | /* This is not the generic standard exception_table_entry format */ | ||
154 | #define ARCH_HAS_SORT_EXTABLE | ||
155 | #define ARCH_HAS_SEARCH_EXTABLE | ||
156 | |||
157 | -extern int fixup_exception(struct pt_regs *regs, int trapnr); | ||
158 | -extern bool ex_has_fault_handler(unsigned long ip); | ||
159 | +extern int fixup_exception(struct pt_regs *regs); | ||
160 | extern int early_fixup_exception(unsigned long *ip); | ||
161 | |||
162 | /* | ||
163 | @@ -394,11 +394,7 @@ do { \ | ||
164 | #define __get_user_asm_ex(x, addr, itype, rtype, ltype) \ | ||
165 | asm volatile("1: mov"itype" %1,%"rtype"0\n" \ | ||
166 | "2:\n" \ | ||
167 | - ".section .fixup,\"ax\"\n" \ | ||
168 | - "3:xor"itype" %"rtype"0,%"rtype"0\n" \ | ||
169 | - " jmp 2b\n" \ | ||
170 | - ".previous\n" \ | ||
171 | - _ASM_EXTABLE_EX(1b, 3b) \ | ||
172 | + _ASM_EXTABLE_EX(1b, 2b) \ | ||
173 | : ltype(x) : "m" (__m(addr))) | ||
174 | |||
175 | #define __put_user_nocheck(x, ptr, size) \ | ||
176 | diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c | ||
177 | index e1d1f6cbaf11..023c442c33bb 100644 | ||
178 | --- a/arch/x86/kernel/kprobes/core.c | ||
179 | +++ b/arch/x86/kernel/kprobes/core.c | ||
180 | @@ -1000,7 +1000,7 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr) | ||
181 | * In case the user-specified fault handler returned | ||
182 | * zero, try to fix up. | ||
183 | */ | ||
184 | - if (fixup_exception(regs, trapnr)) | ||
185 | + if (fixup_exception(regs)) | ||
186 | return 1; | ||
187 | |||
188 | /* | ||
189 | diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c | ||
190 | index 5621f882645e..679302c312f8 100644 | ||
191 | --- a/arch/x86/kernel/traps.c | ||
192 | +++ b/arch/x86/kernel/traps.c | ||
193 | @@ -199,7 +199,7 @@ do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str, | ||
194 | } | ||
195 | |||
196 | if (!user_mode(regs)) { | ||
197 | - if (!fixup_exception(regs, trapnr)) { | ||
198 | + if (!fixup_exception(regs)) { | ||
199 | tsk->thread.error_code = error_code; | ||
200 | tsk->thread.trap_nr = trapnr; | ||
201 | die(str, regs, error_code); | ||
202 | @@ -453,7 +453,7 @@ do_general_protection(struct pt_regs *regs, long error_code) | ||
203 | |||
204 | tsk = current; | ||
205 | if (!user_mode(regs)) { | ||
206 | - if (fixup_exception(regs, X86_TRAP_GP)) | ||
207 | + if (fixup_exception(regs)) | ||
208 | return; | ||
209 | |||
210 | tsk->thread.error_code = error_code; | ||
211 | @@ -699,7 +699,7 @@ static void math_error(struct pt_regs *regs, int error_code, int trapnr) | ||
212 | conditional_sti(regs); | ||
213 | |||
214 | if (!user_mode(regs)) { | ||
215 | - if (!fixup_exception(regs, trapnr)) { | ||
216 | + if (!fixup_exception(regs)) { | ||
217 | task->thread.error_code = error_code; | ||
218 | task->thread.trap_nr = trapnr; | ||
219 | die(str, regs, error_code); | ||
220 | diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c | ||
221 | index 9dd7e4b7fcde..903ec1e9c326 100644 | ||
222 | --- a/arch/x86/mm/extable.c | ||
223 | +++ b/arch/x86/mm/extable.c | ||
224 | @@ -3,9 +3,6 @@ | ||
225 | #include <linux/sort.h> | ||
226 | #include <asm/uaccess.h> | ||
227 | |||
228 | -typedef bool (*ex_handler_t)(const struct exception_table_entry *, | ||
229 | - struct pt_regs *, int); | ||
230 | - | ||
231 | static inline unsigned long | ||
232 | ex_insn_addr(const struct exception_table_entry *x) | ||
233 | { | ||
234 | @@ -16,56 +13,11 @@ ex_fixup_addr(const struct exception_table_entry *x) | ||
235 | { | ||
236 | return (unsigned long)&x->fixup + x->fixup; | ||
237 | } | ||
238 | -static inline ex_handler_t | ||
239 | -ex_fixup_handler(const struct exception_table_entry *x) | ||
240 | -{ | ||
241 | - return (ex_handler_t)((unsigned long)&x->handler + x->handler); | ||
242 | -} | ||
243 | - | ||
244 | -bool ex_handler_default(const struct exception_table_entry *fixup, | ||
245 | - struct pt_regs *regs, int trapnr) | ||
246 | -{ | ||
247 | - regs->ip = ex_fixup_addr(fixup); | ||
248 | - return true; | ||
249 | -} | ||
250 | -EXPORT_SYMBOL(ex_handler_default); | ||
251 | - | ||
252 | -bool ex_handler_fault(const struct exception_table_entry *fixup, | ||
253 | - struct pt_regs *regs, int trapnr) | ||
254 | -{ | ||
255 | - regs->ip = ex_fixup_addr(fixup); | ||
256 | - regs->ax = trapnr; | ||
257 | - return true; | ||
258 | -} | ||
259 | -EXPORT_SYMBOL_GPL(ex_handler_fault); | ||
260 | - | ||
261 | -bool ex_handler_ext(const struct exception_table_entry *fixup, | ||
262 | - struct pt_regs *regs, int trapnr) | ||
263 | -{ | ||
264 | - /* Special hack for uaccess_err */ | ||
265 | - current_thread_info()->uaccess_err = 1; | ||
266 | - regs->ip = ex_fixup_addr(fixup); | ||
267 | - return true; | ||
268 | -} | ||
269 | -EXPORT_SYMBOL(ex_handler_ext); | ||
270 | - | ||
271 | -bool ex_has_fault_handler(unsigned long ip) | ||
272 | -{ | ||
273 | - const struct exception_table_entry *e; | ||
274 | - ex_handler_t handler; | ||
275 | - | ||
276 | - e = search_exception_tables(ip); | ||
277 | - if (!e) | ||
278 | - return false; | ||
279 | - handler = ex_fixup_handler(e); | ||
280 | - | ||
281 | - return handler == ex_handler_fault; | ||
282 | -} | ||
283 | |||
284 | -int fixup_exception(struct pt_regs *regs, int trapnr) | ||
285 | +int fixup_exception(struct pt_regs *regs) | ||
286 | { | ||
287 | - const struct exception_table_entry *e; | ||
288 | - ex_handler_t handler; | ||
289 | + const struct exception_table_entry *fixup; | ||
290 | + unsigned long new_ip; | ||
291 | |||
292 | #ifdef CONFIG_PNPBIOS | ||
293 | if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) { | ||
294 | @@ -81,34 +33,42 @@ int fixup_exception(struct pt_regs *regs, int trapnr) | ||
295 | } | ||
296 | #endif | ||
297 | |||
298 | - e = search_exception_tables(regs->ip); | ||
299 | - if (!e) | ||
300 | - return 0; | ||
301 | + fixup = search_exception_tables(regs->ip); | ||
302 | + if (fixup) { | ||
303 | + new_ip = ex_fixup_addr(fixup); | ||
304 | + | ||
305 | + if (fixup->fixup - fixup->insn >= 0x7ffffff0 - 4) { | ||
306 | + /* Special hack for uaccess_err */ | ||
307 | + current_thread_info()->uaccess_err = 1; | ||
308 | + new_ip -= 0x7ffffff0; | ||
309 | + } | ||
310 | + regs->ip = new_ip; | ||
311 | + return 1; | ||
312 | + } | ||
313 | |||
314 | - handler = ex_fixup_handler(e); | ||
315 | - return handler(e, regs, trapnr); | ||
316 | + return 0; | ||
317 | } | ||
318 | |||
319 | /* Restricted version used during very early boot */ | ||
320 | int __init early_fixup_exception(unsigned long *ip) | ||
321 | { | ||
322 | - const struct exception_table_entry *e; | ||
323 | + const struct exception_table_entry *fixup; | ||
324 | unsigned long new_ip; | ||
325 | - ex_handler_t handler; | ||
326 | |||
327 | - e = search_exception_tables(*ip); | ||
328 | - if (!e) | ||
329 | - return 0; | ||
330 | + fixup = search_exception_tables(*ip); | ||
331 | + if (fixup) { | ||
332 | + new_ip = ex_fixup_addr(fixup); | ||
333 | |||
334 | - new_ip = ex_fixup_addr(e); | ||
335 | - handler = ex_fixup_handler(e); | ||
336 | + if (fixup->fixup - fixup->insn >= 0x7ffffff0 - 4) { | ||
337 | + /* uaccess handling not supported during early boot */ | ||
338 | + return 0; | ||
339 | + } | ||
340 | |||
341 | - /* special handling not supported during early boot */ | ||
342 | - if (handler != ex_handler_default) | ||
343 | - return 0; | ||
344 | + *ip = new_ip; | ||
345 | + return 1; | ||
346 | + } | ||
347 | |||
348 | - *ip = new_ip; | ||
349 | - return 1; | ||
350 | + return 0; | ||
351 | } | ||
352 | |||
353 | /* | ||
354 | @@ -173,8 +133,6 @@ void sort_extable(struct exception_table_entry *start, | ||
355 | i += 4; | ||
356 | p->fixup += i; | ||
357 | i += 4; | ||
358 | - p->handler += i; | ||
359 | - i += 4; | ||
360 | } | ||
361 | |||
362 | sort(start, finish - start, sizeof(struct exception_table_entry), | ||
363 | @@ -187,8 +145,6 @@ void sort_extable(struct exception_table_entry *start, | ||
364 | i += 4; | ||
365 | p->fixup -= i; | ||
366 | i += 4; | ||
367 | - p->handler -= i; | ||
368 | - i += 4; | ||
369 | } | ||
370 | } | ||
371 | |||
372 | diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c | ||
373 | index 03898aea6e0f..e830c71a1323 100644 | ||
374 | --- a/arch/x86/mm/fault.c | ||
375 | +++ b/arch/x86/mm/fault.c | ||
376 | @@ -663,7 +663,7 @@ no_context(struct pt_regs *regs, unsigned long error_code, | ||
377 | int sig; | ||
378 | |||
379 | /* Are we prepared to handle this kernel fault? */ | ||
380 | - if (fixup_exception(regs, X86_TRAP_PF)) { | ||
381 | + if (fixup_exception(regs)) { | ||
382 | /* | ||
383 | * Any interrupt that takes a fault gets the fixup. This makes | ||
384 | * the below recursive fault logic only apply to a faults from | ||
385 | diff --git a/scripts/sortextable.c b/scripts/sortextable.c | ||
386 | index 7b29fb14f870..c2423d913b46 100644 | ||
387 | --- a/scripts/sortextable.c | ||
388 | +++ b/scripts/sortextable.c | ||
389 | @@ -209,35 +209,6 @@ static int compare_relative_table(const void *a, const void *b) | ||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | -static void x86_sort_relative_table(char *extab_image, int image_size) | ||
394 | -{ | ||
395 | - int i; | ||
396 | - | ||
397 | - i = 0; | ||
398 | - while (i < image_size) { | ||
399 | - uint32_t *loc = (uint32_t *)(extab_image + i); | ||
400 | - | ||
401 | - w(r(loc) + i, loc); | ||
402 | - w(r(loc + 1) + i + 4, loc + 1); | ||
403 | - w(r(loc + 2) + i + 8, loc + 2); | ||
404 | - | ||
405 | - i += sizeof(uint32_t) * 3; | ||
406 | - } | ||
407 | - | ||
408 | - qsort(extab_image, image_size / 12, 12, compare_relative_table); | ||
409 | - | ||
410 | - i = 0; | ||
411 | - while (i < image_size) { | ||
412 | - uint32_t *loc = (uint32_t *)(extab_image + i); | ||
413 | - | ||
414 | - w(r(loc) - i, loc); | ||
415 | - w(r(loc + 1) - (i + 4), loc + 1); | ||
416 | - w(r(loc + 2) - (i + 8), loc + 2); | ||
417 | - | ||
418 | - i += sizeof(uint32_t) * 3; | ||
419 | - } | ||
420 | -} | ||
421 | - | ||
422 | static void sort_relative_table(char *extab_image, int image_size) | ||
423 | { | ||
424 | int i; | ||
425 | @@ -310,9 +281,6 @@ do_file(char const *const fname) | ||
426 | break; | ||
427 | case EM_386: | ||
428 | case EM_X86_64: | ||
429 | - custom_sort = x86_sort_relative_table; | ||
430 | - break; | ||
431 | - | ||
432 | case EM_S390: | ||
433 | custom_sort = sort_relative_table; | ||
434 | break; |