diff options
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 155 |
1 files changed, 82 insertions, 73 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index f1961c07af9a..c1afa990a6c8 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -13,13 +13,13 @@ | |||
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | 14 | ||
15 | #include <asm/stackprotector.h> | 15 | #include <asm/stackprotector.h> |
16 | #include <asm/perf_counter.h> | 16 | #include <asm/perf_event.h> |
17 | #include <asm/mmu_context.h> | 17 | #include <asm/mmu_context.h> |
18 | #include <asm/hypervisor.h> | 18 | #include <asm/hypervisor.h> |
19 | #include <asm/processor.h> | 19 | #include <asm/processor.h> |
20 | #include <asm/sections.h> | 20 | #include <asm/sections.h> |
21 | #include <asm/topology.h> | 21 | #include <linux/topology.h> |
22 | #include <asm/cpumask.h> | 22 | #include <linux/cpumask.h> |
23 | #include <asm/pgtable.h> | 23 | #include <asm/pgtable.h> |
24 | #include <asm/atomic.h> | 24 | #include <asm/atomic.h> |
25 | #include <asm/proto.h> | 25 | #include <asm/proto.h> |
@@ -28,13 +28,12 @@ | |||
28 | #include <asm/desc.h> | 28 | #include <asm/desc.h> |
29 | #include <asm/i387.h> | 29 | #include <asm/i387.h> |
30 | #include <asm/mtrr.h> | 30 | #include <asm/mtrr.h> |
31 | #include <asm/numa.h> | 31 | #include <linux/numa.h> |
32 | #include <asm/asm.h> | 32 | #include <asm/asm.h> |
33 | #include <asm/cpu.h> | 33 | #include <asm/cpu.h> |
34 | #include <asm/mce.h> | 34 | #include <asm/mce.h> |
35 | #include <asm/msr.h> | 35 | #include <asm/msr.h> |
36 | #include <asm/pat.h> | 36 | #include <asm/pat.h> |
37 | #include <asm/smp.h> | ||
38 | 37 | ||
39 | #ifdef CONFIG_X86_LOCAL_APIC | 38 | #ifdef CONFIG_X86_LOCAL_APIC |
40 | #include <asm/uv/uv.h> | 39 | #include <asm/uv/uv.h> |
@@ -59,7 +58,30 @@ void __init setup_cpu_local_masks(void) | |||
59 | alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask); | 58 | alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask); |
60 | } | 59 | } |
61 | 60 | ||
62 | static const struct cpu_dev *this_cpu __cpuinitdata; | 61 | static void __cpuinit default_init(struct cpuinfo_x86 *c) |
62 | { | ||
63 | #ifdef CONFIG_X86_64 | ||
64 | cpu_detect_cache_sizes(c); | ||
65 | #else | ||
66 | /* Not much we can do here... */ | ||
67 | /* Check if at least it has cpuid */ | ||
68 | if (c->cpuid_level == -1) { | ||
69 | /* No cpuid. It must be an ancient CPU */ | ||
70 | if (c->x86 == 4) | ||
71 | strcpy(c->x86_model_id, "486"); | ||
72 | else if (c->x86 == 3) | ||
73 | strcpy(c->x86_model_id, "386"); | ||
74 | } | ||
75 | #endif | ||
76 | } | ||
77 | |||
78 | static const struct cpu_dev __cpuinitconst default_cpu = { | ||
79 | .c_init = default_init, | ||
80 | .c_vendor = "Unknown", | ||
81 | .c_x86_vendor = X86_VENDOR_UNKNOWN, | ||
82 | }; | ||
83 | |||
84 | static const struct cpu_dev *this_cpu __cpuinitdata = &default_cpu; | ||
63 | 85 | ||
64 | DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { | 86 | DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { |
65 | #ifdef CONFIG_X86_64 | 87 | #ifdef CONFIG_X86_64 |
@@ -71,45 +93,45 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { | |||
71 | * TLS descriptors are currently at a different place compared to i386. | 93 | * TLS descriptors are currently at a different place compared to i386. |
72 | * Hopefully nobody expects them at a fixed place (Wine?) | 94 | * Hopefully nobody expects them at a fixed place (Wine?) |
73 | */ | 95 | */ |
74 | [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } }, | 96 | [GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff), |
75 | [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } }, | 97 | [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xa09b, 0, 0xfffff), |
76 | [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } }, | 98 | [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc093, 0, 0xfffff), |
77 | [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } }, | 99 | [GDT_ENTRY_DEFAULT_USER32_CS] = GDT_ENTRY_INIT(0xc0fb, 0, 0xfffff), |
78 | [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } }, | 100 | [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f3, 0, 0xfffff), |
79 | [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } }, | 101 | [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xa0fb, 0, 0xfffff), |
80 | #else | 102 | #else |
81 | [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } }, | 103 | [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xc09a, 0, 0xfffff), |
82 | [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } }, | 104 | [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), |
83 | [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } }, | 105 | [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xc0fa, 0, 0xfffff), |
84 | [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } }, | 106 | [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f2, 0, 0xfffff), |
85 | /* | 107 | /* |
86 | * Segments used for calling PnP BIOS have byte granularity. | 108 | * Segments used for calling PnP BIOS have byte granularity. |
87 | * They code segments and data segments have fixed 64k limits, | 109 | * They code segments and data segments have fixed 64k limits, |
88 | * the transfer segment sizes are set at run time. | 110 | * the transfer segment sizes are set at run time. |
89 | */ | 111 | */ |
90 | /* 32-bit code */ | 112 | /* 32-bit code */ |
91 | [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } }, | 113 | [GDT_ENTRY_PNPBIOS_CS32] = GDT_ENTRY_INIT(0x409a, 0, 0xffff), |
92 | /* 16-bit code */ | 114 | /* 16-bit code */ |
93 | [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } }, | 115 | [GDT_ENTRY_PNPBIOS_CS16] = GDT_ENTRY_INIT(0x009a, 0, 0xffff), |
94 | /* 16-bit data */ | 116 | /* 16-bit data */ |
95 | [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } }, | 117 | [GDT_ENTRY_PNPBIOS_DS] = GDT_ENTRY_INIT(0x0092, 0, 0xffff), |
96 | /* 16-bit data */ | 118 | /* 16-bit data */ |
97 | [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } }, | 119 | [GDT_ENTRY_PNPBIOS_TS1] = GDT_ENTRY_INIT(0x0092, 0, 0), |
98 | /* 16-bit data */ | 120 | /* 16-bit data */ |
99 | [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } }, | 121 | [GDT_ENTRY_PNPBIOS_TS2] = GDT_ENTRY_INIT(0x0092, 0, 0), |
100 | /* | 122 | /* |
101 | * The APM segments have byte granularity and their bases | 123 | * The APM segments have byte granularity and their bases |
102 | * are set at run time. All have 64k limits. | 124 | * are set at run time. All have 64k limits. |
103 | */ | 125 | */ |
104 | /* 32-bit code */ | 126 | /* 32-bit code */ |
105 | [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } }, | 127 | [GDT_ENTRY_APMBIOS_BASE] = GDT_ENTRY_INIT(0x409a, 0, 0xffff), |
106 | /* 16-bit code */ | 128 | /* 16-bit code */ |
107 | [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } }, | 129 | [GDT_ENTRY_APMBIOS_BASE+1] = GDT_ENTRY_INIT(0x009a, 0, 0xffff), |
108 | /* data */ | 130 | /* data */ |
109 | [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } }, | 131 | [GDT_ENTRY_APMBIOS_BASE+2] = GDT_ENTRY_INIT(0x4092, 0, 0xffff), |
110 | 132 | ||
111 | [GDT_ENTRY_ESPFIX_SS] = { { { 0x0000ffff, 0x00cf9200 } } }, | 133 | [GDT_ENTRY_ESPFIX_SS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), |
112 | [GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } }, | 134 | [GDT_ENTRY_PERCPU] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), |
113 | GDT_STACK_CANARY_INIT | 135 | GDT_STACK_CANARY_INIT |
114 | #endif | 136 | #endif |
115 | } }; | 137 | } }; |
@@ -332,29 +354,6 @@ void switch_to_new_gdt(int cpu) | |||
332 | 354 | ||
333 | static const struct cpu_dev *__cpuinitdata cpu_devs[X86_VENDOR_NUM] = {}; | 355 | static const struct cpu_dev *__cpuinitdata cpu_devs[X86_VENDOR_NUM] = {}; |
334 | 356 | ||
335 | static void __cpuinit default_init(struct cpuinfo_x86 *c) | ||
336 | { | ||
337 | #ifdef CONFIG_X86_64 | ||
338 | display_cacheinfo(c); | ||
339 | #else | ||
340 | /* Not much we can do here... */ | ||
341 | /* Check if at least it has cpuid */ | ||
342 | if (c->cpuid_level == -1) { | ||
343 | /* No cpuid. It must be an ancient CPU */ | ||
344 | if (c->x86 == 4) | ||
345 | strcpy(c->x86_model_id, "486"); | ||
346 | else if (c->x86 == 3) | ||
347 | strcpy(c->x86_model_id, "386"); | ||
348 | } | ||
349 | #endif | ||
350 | } | ||
351 | |||
352 | static const struct cpu_dev __cpuinitconst default_cpu = { | ||
353 | .c_init = default_init, | ||
354 | .c_vendor = "Unknown", | ||
355 | .c_x86_vendor = X86_VENDOR_UNKNOWN, | ||
356 | }; | ||
357 | |||
358 | static void __cpuinit get_model_name(struct cpuinfo_x86 *c) | 357 | static void __cpuinit get_model_name(struct cpuinfo_x86 *c) |
359 | { | 358 | { |
360 | unsigned int *v; | 359 | unsigned int *v; |
@@ -384,7 +383,7 @@ static void __cpuinit get_model_name(struct cpuinfo_x86 *c) | |||
384 | } | 383 | } |
385 | } | 384 | } |
386 | 385 | ||
387 | void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) | 386 | void __cpuinit cpu_detect_cache_sizes(struct cpuinfo_x86 *c) |
388 | { | 387 | { |
389 | unsigned int n, dummy, ebx, ecx, edx, l2size; | 388 | unsigned int n, dummy, ebx, ecx, edx, l2size; |
390 | 389 | ||
@@ -392,8 +391,6 @@ void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) | |||
392 | 391 | ||
393 | if (n >= 0x80000005) { | 392 | if (n >= 0x80000005) { |
394 | cpuid(0x80000005, &dummy, &ebx, &ecx, &edx); | 393 | cpuid(0x80000005, &dummy, &ebx, &ecx, &edx); |
395 | printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n", | ||
396 | edx>>24, edx&0xFF, ecx>>24, ecx&0xFF); | ||
397 | c->x86_cache_size = (ecx>>24) + (edx>>24); | 394 | c->x86_cache_size = (ecx>>24) + (edx>>24); |
398 | #ifdef CONFIG_X86_64 | 395 | #ifdef CONFIG_X86_64 |
399 | /* On K8 L1 TLB is inclusive, so don't count it */ | 396 | /* On K8 L1 TLB is inclusive, so don't count it */ |
@@ -423,9 +420,6 @@ void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) | |||
423 | #endif | 420 | #endif |
424 | 421 | ||
425 | c->x86_cache_size = l2size; | 422 | c->x86_cache_size = l2size; |
426 | |||
427 | printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n", | ||
428 | l2size, ecx & 0xFF); | ||
429 | } | 423 | } |
430 | 424 | ||
431 | void __cpuinit detect_ht(struct cpuinfo_x86 *c) | 425 | void __cpuinit detect_ht(struct cpuinfo_x86 *c) |
@@ -660,24 +654,31 @@ void __init early_cpu_init(void) | |||
660 | const struct cpu_dev *const *cdev; | 654 | const struct cpu_dev *const *cdev; |
661 | int count = 0; | 655 | int count = 0; |
662 | 656 | ||
657 | #ifdef PROCESSOR_SELECT | ||
663 | printk(KERN_INFO "KERNEL supported cpus:\n"); | 658 | printk(KERN_INFO "KERNEL supported cpus:\n"); |
659 | #endif | ||
660 | |||
664 | for (cdev = __x86_cpu_dev_start; cdev < __x86_cpu_dev_end; cdev++) { | 661 | for (cdev = __x86_cpu_dev_start; cdev < __x86_cpu_dev_end; cdev++) { |
665 | const struct cpu_dev *cpudev = *cdev; | 662 | const struct cpu_dev *cpudev = *cdev; |
666 | unsigned int j; | ||
667 | 663 | ||
668 | if (count >= X86_VENDOR_NUM) | 664 | if (count >= X86_VENDOR_NUM) |
669 | break; | 665 | break; |
670 | cpu_devs[count] = cpudev; | 666 | cpu_devs[count] = cpudev; |
671 | count++; | 667 | count++; |
672 | 668 | ||
673 | for (j = 0; j < 2; j++) { | 669 | #ifdef PROCESSOR_SELECT |
674 | if (!cpudev->c_ident[j]) | 670 | { |
675 | continue; | 671 | unsigned int j; |
676 | printk(KERN_INFO " %s %s\n", cpudev->c_vendor, | 672 | |
677 | cpudev->c_ident[j]); | 673 | for (j = 0; j < 2; j++) { |
674 | if (!cpudev->c_ident[j]) | ||
675 | continue; | ||
676 | printk(KERN_INFO " %s %s\n", cpudev->c_vendor, | ||
677 | cpudev->c_ident[j]); | ||
678 | } | ||
678 | } | 679 | } |
680 | #endif | ||
679 | } | 681 | } |
680 | |||
681 | early_identify_cpu(&boot_cpu_data); | 682 | early_identify_cpu(&boot_cpu_data); |
682 | } | 683 | } |
683 | 684 | ||
@@ -838,10 +839,8 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
838 | boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; | 839 | boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; |
839 | } | 840 | } |
840 | 841 | ||
841 | #ifdef CONFIG_X86_MCE | ||
842 | /* Init Machine Check Exception if available. */ | 842 | /* Init Machine Check Exception if available. */ |
843 | mcheck_init(c); | 843 | mcheck_cpu_init(c); |
844 | #endif | ||
845 | 844 | ||
846 | select_idle_routine(c); | 845 | select_idle_routine(c); |
847 | 846 | ||
@@ -870,7 +869,7 @@ void __init identify_boot_cpu(void) | |||
870 | #else | 869 | #else |
871 | vgetcpu_set_mode(); | 870 | vgetcpu_set_mode(); |
872 | #endif | 871 | #endif |
873 | init_hw_perf_counters(); | 872 | init_hw_perf_events(); |
874 | } | 873 | } |
875 | 874 | ||
876 | void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) | 875 | void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) |
@@ -982,18 +981,26 @@ static __init int setup_disablecpuid(char *arg) | |||
982 | __setup("clearcpuid=", setup_disablecpuid); | 981 | __setup("clearcpuid=", setup_disablecpuid); |
983 | 982 | ||
984 | #ifdef CONFIG_X86_64 | 983 | #ifdef CONFIG_X86_64 |
985 | struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; | 984 | struct desc_ptr idt_descr = { NR_VECTORS * 16 - 1, (unsigned long) idt_table }; |
986 | 985 | ||
987 | DEFINE_PER_CPU_FIRST(union irq_stack_union, | 986 | DEFINE_PER_CPU_FIRST(union irq_stack_union, |
988 | irq_stack_union) __aligned(PAGE_SIZE); | 987 | irq_stack_union) __aligned(PAGE_SIZE); |
989 | 988 | ||
990 | DEFINE_PER_CPU(char *, irq_stack_ptr) = | 989 | /* |
991 | init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64; | 990 | * The following four percpu variables are hot. Align current_task to |
991 | * cacheline size such that all four fall in the same cacheline. | ||
992 | */ | ||
993 | DEFINE_PER_CPU(struct task_struct *, current_task) ____cacheline_aligned = | ||
994 | &init_task; | ||
995 | EXPORT_PER_CPU_SYMBOL(current_task); | ||
992 | 996 | ||
993 | DEFINE_PER_CPU(unsigned long, kernel_stack) = | 997 | DEFINE_PER_CPU(unsigned long, kernel_stack) = |
994 | (unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE; | 998 | (unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE; |
995 | EXPORT_PER_CPU_SYMBOL(kernel_stack); | 999 | EXPORT_PER_CPU_SYMBOL(kernel_stack); |
996 | 1000 | ||
1001 | DEFINE_PER_CPU(char *, irq_stack_ptr) = | ||
1002 | init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64; | ||
1003 | |||
997 | DEFINE_PER_CPU(unsigned int, irq_count) = -1; | 1004 | DEFINE_PER_CPU(unsigned int, irq_count) = -1; |
998 | 1005 | ||
999 | /* | 1006 | /* |
@@ -1008,8 +1015,7 @@ static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = { | |||
1008 | }; | 1015 | }; |
1009 | 1016 | ||
1010 | static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks | 1017 | static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks |
1011 | [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]) | 1018 | [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]); |
1012 | __aligned(PAGE_SIZE); | ||
1013 | 1019 | ||
1014 | /* May not be marked __init: used by software suspend */ | 1020 | /* May not be marked __init: used by software suspend */ |
1015 | void syscall_init(void) | 1021 | void syscall_init(void) |
@@ -1042,8 +1048,11 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist); | |||
1042 | 1048 | ||
1043 | #else /* CONFIG_X86_64 */ | 1049 | #else /* CONFIG_X86_64 */ |
1044 | 1050 | ||
1051 | DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; | ||
1052 | EXPORT_PER_CPU_SYMBOL(current_task); | ||
1053 | |||
1045 | #ifdef CONFIG_CC_STACKPROTECTOR | 1054 | #ifdef CONFIG_CC_STACKPROTECTOR |
1046 | DEFINE_PER_CPU(unsigned long, stack_canary); | 1055 | DEFINE_PER_CPU_ALIGNED(struct stack_canary, stack_canary); |
1047 | #endif | 1056 | #endif |
1048 | 1057 | ||
1049 | /* Make sure %fs and %gs are initialized properly in idle threads */ | 1058 | /* Make sure %fs and %gs are initialized properly in idle threads */ |
@@ -1127,7 +1136,7 @@ void __cpuinit cpu_init(void) | |||
1127 | wrmsrl(MSR_KERNEL_GS_BASE, 0); | 1136 | wrmsrl(MSR_KERNEL_GS_BASE, 0); |
1128 | barrier(); | 1137 | barrier(); |
1129 | 1138 | ||
1130 | check_efer(); | 1139 | x86_configure_nx(); |
1131 | if (cpu != 0) | 1140 | if (cpu != 0) |
1132 | enable_x2apic(); | 1141 | enable_x2apic(); |
1133 | 1142 | ||