diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-05 13:03:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-05 13:03:48 -0400 |
commit | 51d0f0cb3ae0da0ce5bb0bff8d1305345e6ec7ec (patch) | |
tree | 9f1be28982bca81b19887f47cd85dc7898c6f831 /arch | |
parent | a0e9c6efa585897f00eb22e67887e5a25482b1b8 (diff) | |
parent | 425be5679fd292a3c36cb1fe423086708a99f11a (diff) |
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Ingo Molnar:
"Misc fixes:
- early_idt_handlers[] fix that fixes the build with bleeding edge
tooling
- build warning fix on GCC 5.1
- vm86 fix plus self-test to make it harder to break it again"
* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/asm/irq: Stop relying on magic JMP behavior for early_idt_handlers
x86/asm/entry/32, selftests: Add a selftest for kernel entries from VM86 mode
x86/boot: Add CONFIG_PARAVIRT_SPINLOCKS quirk to arch/x86/boot/compressed/misc.h
x86/asm/entry/32: Really make user_mode() work correctly for VM86 mode
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/boot/compressed/misc.h | 11 | ||||
-rw-r--r-- | arch/x86/include/asm/ptrace.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/segment.h | 14 | ||||
-rw-r--r-- | arch/x86/kernel/head64.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/head_32.S | 33 | ||||
-rw-r--r-- | arch/x86/kernel/head_64.S | 20 |
6 files changed, 48 insertions, 34 deletions
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index 89dd0d78013a..805d25ca5f1d 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h | |||
@@ -2,15 +2,14 @@ | |||
2 | #define BOOT_COMPRESSED_MISC_H | 2 | #define BOOT_COMPRESSED_MISC_H |
3 | 3 | ||
4 | /* | 4 | /* |
5 | * we have to be careful, because no indirections are allowed here, and | 5 | * Special hack: we have to be careful, because no indirections are allowed here, |
6 | * paravirt_ops is a kind of one. As it will only run in baremetal anyway, | 6 | * and paravirt_ops is a kind of one. As it will only run in baremetal anyway, |
7 | * we just keep it from happening | 7 | * we just keep it from happening. (This list needs to be extended when new |
8 | * paravirt and debugging variants are added.) | ||
8 | */ | 9 | */ |
9 | #undef CONFIG_PARAVIRT | 10 | #undef CONFIG_PARAVIRT |
11 | #undef CONFIG_PARAVIRT_SPINLOCKS | ||
10 | #undef CONFIG_KASAN | 12 | #undef CONFIG_KASAN |
11 | #ifdef CONFIG_X86_32 | ||
12 | #define _ASM_X86_DESC_H 1 | ||
13 | #endif | ||
14 | 13 | ||
15 | #include <linux/linkage.h> | 14 | #include <linux/linkage.h> |
16 | #include <linux/screen_info.h> | 15 | #include <linux/screen_info.h> |
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 19507ffa5d28..5fabf1362942 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h | |||
@@ -107,7 +107,7 @@ static inline unsigned long regs_return_value(struct pt_regs *regs) | |||
107 | static inline int user_mode(struct pt_regs *regs) | 107 | static inline int user_mode(struct pt_regs *regs) |
108 | { | 108 | { |
109 | #ifdef CONFIG_X86_32 | 109 | #ifdef CONFIG_X86_32 |
110 | return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL; | 110 | return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >= USER_RPL; |
111 | #else | 111 | #else |
112 | return !!(regs->cs & 3); | 112 | return !!(regs->cs & 3); |
113 | #endif | 113 | #endif |
diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index 5a9856eb12ba..7d5a1929d76b 100644 --- a/arch/x86/include/asm/segment.h +++ b/arch/x86/include/asm/segment.h | |||
@@ -231,11 +231,21 @@ | |||
231 | #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES* 8) | 231 | #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES* 8) |
232 | 232 | ||
233 | #ifdef __KERNEL__ | 233 | #ifdef __KERNEL__ |
234 | |||
235 | /* | ||
236 | * early_idt_handler_array is an array of entry points referenced in the | ||
237 | * early IDT. For simplicity, it's a real array with one entry point | ||
238 | * every nine bytes. That leaves room for an optional 'push $0' if the | ||
239 | * vector has no error code (two bytes), a 'push $vector_number' (two | ||
240 | * bytes), and a jump to the common entry code (up to five bytes). | ||
241 | */ | ||
242 | #define EARLY_IDT_HANDLER_SIZE 9 | ||
243 | |||
234 | #ifndef __ASSEMBLY__ | 244 | #ifndef __ASSEMBLY__ |
235 | 245 | ||
236 | extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5]; | 246 | extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE]; |
237 | #ifdef CONFIG_TRACING | 247 | #ifdef CONFIG_TRACING |
238 | # define trace_early_idt_handlers early_idt_handlers | 248 | # define trace_early_idt_handler_array early_idt_handler_array |
239 | #endif | 249 | #endif |
240 | 250 | ||
241 | /* | 251 | /* |
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 2b55ee6db053..5a4668136e98 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
@@ -167,7 +167,7 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) | |||
167 | clear_bss(); | 167 | clear_bss(); |
168 | 168 | ||
169 | for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) | 169 | for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) |
170 | set_intr_gate(i, early_idt_handlers[i]); | 170 | set_intr_gate(i, early_idt_handler_array[i]); |
171 | load_idt((const struct desc_ptr *)&idt_descr); | 171 | load_idt((const struct desc_ptr *)&idt_descr); |
172 | 172 | ||
173 | copy_bootdata(__va(real_mode_data)); | 173 | copy_bootdata(__va(real_mode_data)); |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index d031bad9e07e..53eeb226657c 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -478,21 +478,22 @@ is486: | |||
478 | __INIT | 478 | __INIT |
479 | setup_once: | 479 | setup_once: |
480 | /* | 480 | /* |
481 | * Set up a idt with 256 entries pointing to ignore_int, | 481 | * Set up a idt with 256 interrupt gates that push zero if there |
482 | * interrupt gates. It doesn't actually load idt - that needs | 482 | * is no error code and then jump to early_idt_handler_common. |
483 | * to be done on each CPU. Interrupts are enabled elsewhere, | 483 | * It doesn't actually load the idt - that needs to be done on |
484 | * when we can be relatively sure everything is ok. | 484 | * each CPU. Interrupts are enabled elsewhere, when we can be |
485 | * relatively sure everything is ok. | ||
485 | */ | 486 | */ |
486 | 487 | ||
487 | movl $idt_table,%edi | 488 | movl $idt_table,%edi |
488 | movl $early_idt_handlers,%eax | 489 | movl $early_idt_handler_array,%eax |
489 | movl $NUM_EXCEPTION_VECTORS,%ecx | 490 | movl $NUM_EXCEPTION_VECTORS,%ecx |
490 | 1: | 491 | 1: |
491 | movl %eax,(%edi) | 492 | movl %eax,(%edi) |
492 | movl %eax,4(%edi) | 493 | movl %eax,4(%edi) |
493 | /* interrupt gate, dpl=0, present */ | 494 | /* interrupt gate, dpl=0, present */ |
494 | movl $(0x8E000000 + __KERNEL_CS),2(%edi) | 495 | movl $(0x8E000000 + __KERNEL_CS),2(%edi) |
495 | addl $9,%eax | 496 | addl $EARLY_IDT_HANDLER_SIZE,%eax |
496 | addl $8,%edi | 497 | addl $8,%edi |
497 | loop 1b | 498 | loop 1b |
498 | 499 | ||
@@ -524,26 +525,28 @@ setup_once: | |||
524 | andl $0,setup_once_ref /* Once is enough, thanks */ | 525 | andl $0,setup_once_ref /* Once is enough, thanks */ |
525 | ret | 526 | ret |
526 | 527 | ||
527 | ENTRY(early_idt_handlers) | 528 | ENTRY(early_idt_handler_array) |
528 | # 36(%esp) %eflags | 529 | # 36(%esp) %eflags |
529 | # 32(%esp) %cs | 530 | # 32(%esp) %cs |
530 | # 28(%esp) %eip | 531 | # 28(%esp) %eip |
531 | # 24(%rsp) error code | 532 | # 24(%rsp) error code |
532 | i = 0 | 533 | i = 0 |
533 | .rept NUM_EXCEPTION_VECTORS | 534 | .rept NUM_EXCEPTION_VECTORS |
534 | .if (EXCEPTION_ERRCODE_MASK >> i) & 1 | 535 | .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1 |
535 | ASM_NOP2 | ||
536 | .else | ||
537 | pushl $0 # Dummy error code, to make stack frame uniform | 536 | pushl $0 # Dummy error code, to make stack frame uniform |
538 | .endif | 537 | .endif |
539 | pushl $i # 20(%esp) Vector number | 538 | pushl $i # 20(%esp) Vector number |
540 | jmp early_idt_handler | 539 | jmp early_idt_handler_common |
541 | i = i + 1 | 540 | i = i + 1 |
541 | .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc | ||
542 | .endr | 542 | .endr |
543 | ENDPROC(early_idt_handlers) | 543 | ENDPROC(early_idt_handler_array) |
544 | 544 | ||
545 | /* This is global to keep gas from relaxing the jumps */ | 545 | early_idt_handler_common: |
546 | ENTRY(early_idt_handler) | 546 | /* |
547 | * The stack is the hardware frame, an error code or zero, and the | ||
548 | * vector number. | ||
549 | */ | ||
547 | cld | 550 | cld |
548 | 551 | ||
549 | cmpl $2,(%esp) # X86_TRAP_NMI | 552 | cmpl $2,(%esp) # X86_TRAP_NMI |
@@ -603,7 +606,7 @@ ex_entry: | |||
603 | is_nmi: | 606 | is_nmi: |
604 | addl $8,%esp /* drop vector number and error code */ | 607 | addl $8,%esp /* drop vector number and error code */ |
605 | iret | 608 | iret |
606 | ENDPROC(early_idt_handler) | 609 | ENDPROC(early_idt_handler_common) |
607 | 610 | ||
608 | /* This is the default interrupt "handler" :-) */ | 611 | /* This is the default interrupt "handler" :-) */ |
609 | ALIGN | 612 | ALIGN |
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index ae6588b301c2..df7e78057ae0 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S | |||
@@ -321,26 +321,28 @@ bad_address: | |||
321 | jmp bad_address | 321 | jmp bad_address |
322 | 322 | ||
323 | __INIT | 323 | __INIT |
324 | .globl early_idt_handlers | 324 | ENTRY(early_idt_handler_array) |
325 | early_idt_handlers: | ||
326 | # 104(%rsp) %rflags | 325 | # 104(%rsp) %rflags |
327 | # 96(%rsp) %cs | 326 | # 96(%rsp) %cs |
328 | # 88(%rsp) %rip | 327 | # 88(%rsp) %rip |
329 | # 80(%rsp) error code | 328 | # 80(%rsp) error code |
330 | i = 0 | 329 | i = 0 |
331 | .rept NUM_EXCEPTION_VECTORS | 330 | .rept NUM_EXCEPTION_VECTORS |
332 | .if (EXCEPTION_ERRCODE_MASK >> i) & 1 | 331 | .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1 |
333 | ASM_NOP2 | ||
334 | .else | ||
335 | pushq $0 # Dummy error code, to make stack frame uniform | 332 | pushq $0 # Dummy error code, to make stack frame uniform |
336 | .endif | 333 | .endif |
337 | pushq $i # 72(%rsp) Vector number | 334 | pushq $i # 72(%rsp) Vector number |
338 | jmp early_idt_handler | 335 | jmp early_idt_handler_common |
339 | i = i + 1 | 336 | i = i + 1 |
337 | .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc | ||
340 | .endr | 338 | .endr |
339 | ENDPROC(early_idt_handler_array) | ||
341 | 340 | ||
342 | /* This is global to keep gas from relaxing the jumps */ | 341 | early_idt_handler_common: |
343 | ENTRY(early_idt_handler) | 342 | /* |
343 | * The stack is the hardware frame, an error code or zero, and the | ||
344 | * vector number. | ||
345 | */ | ||
344 | cld | 346 | cld |
345 | 347 | ||
346 | cmpl $2,(%rsp) # X86_TRAP_NMI | 348 | cmpl $2,(%rsp) # X86_TRAP_NMI |
@@ -412,7 +414,7 @@ ENTRY(early_idt_handler) | |||
412 | is_nmi: | 414 | is_nmi: |
413 | addq $16,%rsp # drop vector number and error code | 415 | addq $16,%rsp # drop vector number and error code |
414 | INTERRUPT_RETURN | 416 | INTERRUPT_RETURN |
415 | ENDPROC(early_idt_handler) | 417 | ENDPROC(early_idt_handler_common) |
416 | 418 | ||
417 | __INITDATA | 419 | __INITDATA |
418 | 420 | ||