diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/desc.h | 26 | ||||
-rw-r--r-- | arch/x86/include/asm/msr.h | 7 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/apic/probe_32.c | 11 | ||||
-rw-r--r-- | arch/x86/kernel/apic/summit_32.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/entry_32.S | 64 | ||||
-rw-r--r-- | arch/x86/kernel/head_32.S | 1 | ||||
-rw-r--r-- | arch/x86/kernel/head_64.S | 1 |
9 files changed, 47 insertions, 70 deletions
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index c45f415ce315..c993e9e0fed4 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h | |||
@@ -1,7 +1,6 @@ | |||
1 | #ifndef _ASM_X86_DESC_H | 1 | #ifndef _ASM_X86_DESC_H |
2 | #define _ASM_X86_DESC_H | 2 | #define _ASM_X86_DESC_H |
3 | 3 | ||
4 | #ifndef __ASSEMBLY__ | ||
5 | #include <asm/desc_defs.h> | 4 | #include <asm/desc_defs.h> |
6 | #include <asm/ldt.h> | 5 | #include <asm/ldt.h> |
7 | #include <asm/mmu.h> | 6 | #include <asm/mmu.h> |
@@ -380,29 +379,4 @@ static inline void set_system_intr_gate_ist(int n, void *addr, unsigned ist) | |||
380 | _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS); | 379 | _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS); |
381 | } | 380 | } |
382 | 381 | ||
383 | #else | ||
384 | /* | ||
385 | * GET_DESC_BASE reads the descriptor base of the specified segment. | ||
386 | * | ||
387 | * Args: | ||
388 | * idx - descriptor index | ||
389 | * gdt - GDT pointer | ||
390 | * base - 32bit register to which the base will be written | ||
391 | * lo_w - lo word of the "base" register | ||
392 | * lo_b - lo byte of the "base" register | ||
393 | * hi_b - hi byte of the low word of the "base" register | ||
394 | * | ||
395 | * Example: | ||
396 | * GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah) | ||
397 | * Will read the base address of GDT_ENTRY_ESPFIX_SS and put it into %eax. | ||
398 | */ | ||
399 | #define GET_DESC_BASE(idx, gdt, base, lo_w, lo_b, hi_b) \ | ||
400 | movb idx * 8 + 4(gdt), lo_b; \ | ||
401 | movb idx * 8 + 7(gdt), hi_b; \ | ||
402 | shll $16, base; \ | ||
403 | movw idx * 8 + 2(gdt), lo_w; | ||
404 | |||
405 | |||
406 | #endif /* __ASSEMBLY__ */ | ||
407 | |||
408 | #endif /* _ASM_X86_DESC_H */ | 382 | #endif /* _ASM_X86_DESC_H */ |
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 22603764e7db..48ad9d29484a 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h | |||
@@ -3,13 +3,10 @@ | |||
3 | 3 | ||
4 | #include <asm/msr-index.h> | 4 | #include <asm/msr-index.h> |
5 | 5 | ||
6 | #ifndef __ASSEMBLY__ | ||
7 | # include <linux/types.h> | ||
8 | #endif | ||
9 | |||
10 | #ifdef __KERNEL__ | 6 | #ifdef __KERNEL__ |
11 | #ifndef __ASSEMBLY__ | 7 | #ifndef __ASSEMBLY__ |
12 | 8 | ||
9 | #include <linux/types.h> | ||
13 | #include <asm/asm.h> | 10 | #include <asm/asm.h> |
14 | #include <asm/errno.h> | 11 | #include <asm/errno.h> |
15 | #include <asm/cpumask.h> | 12 | #include <asm/cpumask.h> |
@@ -264,6 +261,4 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) | |||
264 | #endif /* CONFIG_SMP */ | 261 | #endif /* CONFIG_SMP */ |
265 | #endif /* __ASSEMBLY__ */ | 262 | #endif /* __ASSEMBLY__ */ |
266 | #endif /* __KERNEL__ */ | 263 | #endif /* __KERNEL__ */ |
267 | |||
268 | |||
269 | #endif /* _ASM_X86_MSR_H */ | 264 | #endif /* _ASM_X86_MSR_H */ |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 29d0752d9517..b7a79207295e 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -2004,7 +2004,9 @@ void disable_IO_APIC(void) | |||
2004 | /* | 2004 | /* |
2005 | * Use virtual wire A mode when interrupt remapping is enabled. | 2005 | * Use virtual wire A mode when interrupt remapping is enabled. |
2006 | */ | 2006 | */ |
2007 | disconnect_bsp_APIC(!intr_remapping_enabled && ioapic_i8259.pin != -1); | 2007 | if (cpu_has_apic) |
2008 | disconnect_bsp_APIC(!intr_remapping_enabled && | ||
2009 | ioapic_i8259.pin != -1); | ||
2008 | } | 2010 | } |
2009 | 2011 | ||
2010 | #ifdef CONFIG_X86_32 | 2012 | #ifdef CONFIG_X86_32 |
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index 440a8bccd91a..0c0182cc947d 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c | |||
@@ -20,23 +20,12 @@ | |||
20 | #include <asm/apic.h> | 20 | #include <asm/apic.h> |
21 | #include <asm/setup.h> | 21 | #include <asm/setup.h> |
22 | 22 | ||
23 | #include <linux/threads.h> | ||
24 | #include <linux/cpumask.h> | ||
25 | #include <asm/mpspec.h> | ||
26 | #include <asm/fixmap.h> | ||
27 | #include <asm/apicdef.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/string.h> | ||
30 | #include <linux/smp.h> | 23 | #include <linux/smp.h> |
31 | #include <linux/init.h> | ||
32 | #include <asm/ipi.h> | 24 | #include <asm/ipi.h> |
33 | 25 | ||
34 | #include <linux/smp.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
37 | #include <asm/acpi.h> | 27 | #include <asm/acpi.h> |
38 | #include <asm/e820.h> | 28 | #include <asm/e820.h> |
39 | #include <asm/setup.h> | ||
40 | 29 | ||
41 | #ifdef CONFIG_HOTPLUG_CPU | 30 | #ifdef CONFIG_HOTPLUG_CPU |
42 | #define DEFAULT_SEND_IPI (1) | 31 | #define DEFAULT_SEND_IPI (1) |
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index 344eee4ac0a4..eafdfbd1ea95 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <asm/ipi.h> | 44 | #include <asm/ipi.h> |
45 | #include <linux/kernel.h> | 45 | #include <linux/kernel.h> |
46 | #include <linux/string.h> | 46 | #include <linux/string.h> |
47 | #include <linux/init.h> | ||
48 | #include <linux/gfp.h> | 47 | #include <linux/gfp.h> |
49 | #include <linux/smp.h> | 48 | #include <linux/smp.h> |
50 | 49 | ||
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 5b9cb8839cae..ba1131ac9434 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -108,7 +108,7 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { | |||
108 | /* data */ | 108 | /* data */ |
109 | [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } }, | 109 | [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } }, |
110 | 110 | ||
111 | [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } }, | 111 | [GDT_ENTRY_ESPFIX_SS] = { { { 0x0000ffff, 0x00cf9200 } } }, |
112 | [GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } }, | 112 | [GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } }, |
113 | GDT_STACK_CANARY_INIT | 113 | GDT_STACK_CANARY_INIT |
114 | #endif | 114 | #endif |
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index c929add475c9..9f8ce77dbc64 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
@@ -48,7 +48,6 @@ | |||
48 | #include <asm/segment.h> | 48 | #include <asm/segment.h> |
49 | #include <asm/smp.h> | 49 | #include <asm/smp.h> |
50 | #include <asm/page_types.h> | 50 | #include <asm/page_types.h> |
51 | #include <asm/desc.h> | ||
52 | #include <asm/percpu.h> | 51 | #include <asm/percpu.h> |
53 | #include <asm/dwarf2.h> | 52 | #include <asm/dwarf2.h> |
54 | #include <asm/processor-flags.h> | 53 | #include <asm/processor-flags.h> |
@@ -84,7 +83,7 @@ | |||
84 | #define preempt_stop(clobbers) DISABLE_INTERRUPTS(clobbers); TRACE_IRQS_OFF | 83 | #define preempt_stop(clobbers) DISABLE_INTERRUPTS(clobbers); TRACE_IRQS_OFF |
85 | #else | 84 | #else |
86 | #define preempt_stop(clobbers) | 85 | #define preempt_stop(clobbers) |
87 | #define resume_kernel restore_nocheck | 86 | #define resume_kernel restore_all |
88 | #endif | 87 | #endif |
89 | 88 | ||
90 | .macro TRACE_IRQS_IRET | 89 | .macro TRACE_IRQS_IRET |
@@ -372,7 +371,7 @@ END(ret_from_exception) | |||
372 | ENTRY(resume_kernel) | 371 | ENTRY(resume_kernel) |
373 | DISABLE_INTERRUPTS(CLBR_ANY) | 372 | DISABLE_INTERRUPTS(CLBR_ANY) |
374 | cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? | 373 | cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? |
375 | jnz restore_nocheck | 374 | jnz restore_all |
376 | need_resched: | 375 | need_resched: |
377 | movl TI_flags(%ebp), %ecx # need_resched set ? | 376 | movl TI_flags(%ebp), %ecx # need_resched set ? |
378 | testb $_TIF_NEED_RESCHED, %cl | 377 | testb $_TIF_NEED_RESCHED, %cl |
@@ -540,6 +539,8 @@ syscall_exit: | |||
540 | jne syscall_exit_work | 539 | jne syscall_exit_work |
541 | 540 | ||
542 | restore_all: | 541 | restore_all: |
542 | TRACE_IRQS_IRET | ||
543 | restore_all_notrace: | ||
543 | movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS | 544 | movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS |
544 | # Warning: PT_OLDSS(%esp) contains the wrong/random values if we | 545 | # Warning: PT_OLDSS(%esp) contains the wrong/random values if we |
545 | # are returning to the kernel. | 546 | # are returning to the kernel. |
@@ -551,8 +552,6 @@ restore_all: | |||
551 | CFI_REMEMBER_STATE | 552 | CFI_REMEMBER_STATE |
552 | je ldt_ss # returning to user-space with LDT SS | 553 | je ldt_ss # returning to user-space with LDT SS |
553 | restore_nocheck: | 554 | restore_nocheck: |
554 | TRACE_IRQS_IRET | ||
555 | restore_nocheck_notrace: | ||
556 | RESTORE_REGS 4 # skip orig_eax/error_code | 555 | RESTORE_REGS 4 # skip orig_eax/error_code |
557 | CFI_ADJUST_CFA_OFFSET -4 | 556 | CFI_ADJUST_CFA_OFFSET -4 |
558 | irq_return: | 557 | irq_return: |
@@ -588,22 +587,34 @@ ldt_ss: | |||
588 | jne restore_nocheck | 587 | jne restore_nocheck |
589 | #endif | 588 | #endif |
590 | 589 | ||
591 | /* If returning to userspace with 16bit stack, | 590 | /* |
592 | * try to fix the higher word of ESP, as the CPU | 591 | * Setup and switch to ESPFIX stack |
593 | * won't restore it. | 592 | * |
594 | * This is an "official" bug of all the x86-compatible | 593 | * We're returning to userspace with a 16 bit stack. The CPU will not |
595 | * CPUs, which we can try to work around to make | 594 | * restore the high word of ESP for us on executing iret... This is an |
596 | * dosemu and wine happy. */ | 595 | * "official" bug of all the x86-compatible CPUs, which we can work |
597 | movl PT_OLDESP(%esp), %eax | 596 | * around to make dosemu and wine happy. We do this by preloading the |
598 | movl %esp, %edx | 597 | * high word of ESP with the high word of the userspace ESP while |
599 | call patch_espfix_desc | 598 | * compensating for the offset by changing to the ESPFIX segment with |
599 | * a base address that matches for the difference. | ||
600 | */ | ||
601 | mov %esp, %edx /* load kernel esp */ | ||
602 | mov PT_OLDESP(%esp), %eax /* load userspace esp */ | ||
603 | mov %dx, %ax /* eax: new kernel esp */ | ||
604 | sub %eax, %edx /* offset (low word is 0) */ | ||
605 | PER_CPU(gdt_page, %ebx) | ||
606 | shr $16, %edx | ||
607 | mov %dl, GDT_ENTRY_ESPFIX_SS * 8 + 4(%ebx) /* bits 16..23 */ | ||
608 | mov %dh, GDT_ENTRY_ESPFIX_SS * 8 + 7(%ebx) /* bits 24..31 */ | ||
600 | pushl $__ESPFIX_SS | 609 | pushl $__ESPFIX_SS |
601 | CFI_ADJUST_CFA_OFFSET 4 | 610 | CFI_ADJUST_CFA_OFFSET 4 |
602 | pushl %eax | 611 | push %eax /* new kernel esp */ |
603 | CFI_ADJUST_CFA_OFFSET 4 | 612 | CFI_ADJUST_CFA_OFFSET 4 |
613 | /* Disable interrupts, but do not irqtrace this section: we | ||
614 | * will soon execute iret and the tracer was already set to | ||
615 | * the irqstate after the iret */ | ||
604 | DISABLE_INTERRUPTS(CLBR_EAX) | 616 | DISABLE_INTERRUPTS(CLBR_EAX) |
605 | TRACE_IRQS_OFF | 617 | lss (%esp), %esp /* switch to espfix segment */ |
606 | lss (%esp), %esp | ||
607 | CFI_ADJUST_CFA_OFFSET -8 | 618 | CFI_ADJUST_CFA_OFFSET -8 |
608 | jmp restore_nocheck | 619 | jmp restore_nocheck |
609 | CFI_ENDPROC | 620 | CFI_ENDPROC |
@@ -716,15 +727,24 @@ PTREGSCALL(vm86) | |||
716 | PTREGSCALL(vm86old) | 727 | PTREGSCALL(vm86old) |
717 | 728 | ||
718 | .macro FIXUP_ESPFIX_STACK | 729 | .macro FIXUP_ESPFIX_STACK |
719 | /* since we are on a wrong stack, we cant make it a C code :( */ | 730 | /* |
731 | * Switch back for ESPFIX stack to the normal zerobased stack | ||
732 | * | ||
733 | * We can't call C functions using the ESPFIX stack. This code reads | ||
734 | * the high word of the segment base from the GDT and swiches to the | ||
735 | * normal stack and adjusts ESP with the matching offset. | ||
736 | */ | ||
737 | /* fixup the stack */ | ||
720 | PER_CPU(gdt_page, %ebx) | 738 | PER_CPU(gdt_page, %ebx) |
721 | GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah) | 739 | mov GDT_ENTRY_ESPFIX_SS * 8 + 4(%ebx), %al /* bits 16..23 */ |
722 | addl %esp, %eax | 740 | mov GDT_ENTRY_ESPFIX_SS * 8 + 7(%ebx), %ah /* bits 24..31 */ |
741 | shl $16, %eax | ||
742 | addl %esp, %eax /* the adjusted stack pointer */ | ||
723 | pushl $__KERNEL_DS | 743 | pushl $__KERNEL_DS |
724 | CFI_ADJUST_CFA_OFFSET 4 | 744 | CFI_ADJUST_CFA_OFFSET 4 |
725 | pushl %eax | 745 | pushl %eax |
726 | CFI_ADJUST_CFA_OFFSET 4 | 746 | CFI_ADJUST_CFA_OFFSET 4 |
727 | lss (%esp), %esp | 747 | lss (%esp), %esp /* switch to the normal stack segment */ |
728 | CFI_ADJUST_CFA_OFFSET -8 | 748 | CFI_ADJUST_CFA_OFFSET -8 |
729 | .endm | 749 | .endm |
730 | .macro UNWIND_ESPFIX_STACK | 750 | .macro UNWIND_ESPFIX_STACK |
@@ -1329,7 +1349,7 @@ nmi_stack_correct: | |||
1329 | xorl %edx,%edx # zero error code | 1349 | xorl %edx,%edx # zero error code |
1330 | movl %esp,%eax # pt_regs pointer | 1350 | movl %esp,%eax # pt_regs pointer |
1331 | call do_nmi | 1351 | call do_nmi |
1332 | jmp restore_nocheck_notrace | 1352 | jmp restore_all_notrace |
1333 | CFI_ENDPROC | 1353 | CFI_ENDPROC |
1334 | 1354 | ||
1335 | nmi_stack_fixup: | 1355 | nmi_stack_fixup: |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index dc5ed4bdd88d..8663afb56535 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <asm/segment.h> | 13 | #include <asm/segment.h> |
14 | #include <asm/page_types.h> | 14 | #include <asm/page_types.h> |
15 | #include <asm/pgtable_types.h> | 15 | #include <asm/pgtable_types.h> |
16 | #include <asm/desc.h> | ||
17 | #include <asm/cache.h> | 16 | #include <asm/cache.h> |
18 | #include <asm/thread_info.h> | 17 | #include <asm/thread_info.h> |
19 | #include <asm/asm-offsets.h> | 18 | #include <asm/asm-offsets.h> |
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 54b29bb24e71..fa54f78e2a05 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/linkage.h> | 12 | #include <linux/linkage.h> |
13 | #include <linux/threads.h> | 13 | #include <linux/threads.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <asm/desc.h> | ||
16 | #include <asm/segment.h> | 15 | #include <asm/segment.h> |
17 | #include <asm/pgtable.h> | 16 | #include <asm/pgtable.h> |
18 | #include <asm/page.h> | 17 | #include <asm/page.h> |