Contents of /trunk/kernel-alx/patches-4.4/0129-4.4.30-all-fixes.patch
Parent Directory | Revision Log
Revision 2865 -
(show annotations)
(download)
Mon Mar 27 13:49:09 2017 UTC (7 years, 6 months ago) by niro
File size: 13181 byte(s)
Mon Mar 27 13:49:09 2017 UTC (7 years, 6 months ago) by niro
File size: 13181 byte(s)
linux-4.4.30
1 | 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; |