diff options
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 77848d9fca68..3ffdcfa9abdf 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -13,6 +13,7 @@ | |||
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/mmu_context.h> | 17 | #include <asm/mmu_context.h> |
17 | #include <asm/hypervisor.h> | 18 | #include <asm/hypervisor.h> |
18 | #include <asm/processor.h> | 19 | #include <asm/processor.h> |
@@ -299,7 +300,8 @@ static const char *__cpuinit table_lookup_model(struct cpuinfo_x86 *c) | |||
299 | return NULL; /* Not found */ | 300 | return NULL; /* Not found */ |
300 | } | 301 | } |
301 | 302 | ||
302 | __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata; | 303 | __u32 cpu_caps_cleared[NCAPINTS] __cpuinitdata; |
304 | __u32 cpu_caps_set[NCAPINTS] __cpuinitdata; | ||
303 | 305 | ||
304 | void load_percpu_segment(int cpu) | 306 | void load_percpu_segment(int cpu) |
305 | { | 307 | { |
@@ -768,6 +770,12 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
768 | if (this_cpu->c_identify) | 770 | if (this_cpu->c_identify) |
769 | this_cpu->c_identify(c); | 771 | this_cpu->c_identify(c); |
770 | 772 | ||
773 | /* Clear/Set all flags overriden by options, after probe */ | ||
774 | for (i = 0; i < NCAPINTS; i++) { | ||
775 | c->x86_capability[i] &= ~cpu_caps_cleared[i]; | ||
776 | c->x86_capability[i] |= cpu_caps_set[i]; | ||
777 | } | ||
778 | |||
771 | #ifdef CONFIG_X86_64 | 779 | #ifdef CONFIG_X86_64 |
772 | c->apicid = apic->phys_pkg_id(c->initial_apicid, 0); | 780 | c->apicid = apic->phys_pkg_id(c->initial_apicid, 0); |
773 | #endif | 781 | #endif |
@@ -813,6 +821,16 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
813 | #endif | 821 | #endif |
814 | 822 | ||
815 | init_hypervisor(c); | 823 | init_hypervisor(c); |
824 | |||
825 | /* | ||
826 | * Clear/Set all flags overriden by options, need do it | ||
827 | * before following smp all cpus cap AND. | ||
828 | */ | ||
829 | for (i = 0; i < NCAPINTS; i++) { | ||
830 | c->x86_capability[i] &= ~cpu_caps_cleared[i]; | ||
831 | c->x86_capability[i] |= cpu_caps_set[i]; | ||
832 | } | ||
833 | |||
816 | /* | 834 | /* |
817 | * On SMP, boot_cpu_data holds the common feature set between | 835 | * On SMP, boot_cpu_data holds the common feature set between |
818 | * all CPUs; so make sure that we indicate which features are | 836 | * all CPUs; so make sure that we indicate which features are |
@@ -825,10 +843,6 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
825 | boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; | 843 | boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; |
826 | } | 844 | } |
827 | 845 | ||
828 | /* Clear all flags overriden by options */ | ||
829 | for (i = 0; i < NCAPINTS; i++) | ||
830 | c->x86_capability[i] &= ~cleared_cpu_caps[i]; | ||
831 | |||
832 | #ifdef CONFIG_X86_MCE | 846 | #ifdef CONFIG_X86_MCE |
833 | /* Init Machine Check Exception if available. */ | 847 | /* Init Machine Check Exception if available. */ |
834 | mcheck_init(c); | 848 | mcheck_init(c); |
@@ -861,6 +875,7 @@ void __init identify_boot_cpu(void) | |||
861 | #else | 875 | #else |
862 | vgetcpu_set_mode(); | 876 | vgetcpu_set_mode(); |
863 | #endif | 877 | #endif |
878 | init_hw_perf_counters(); | ||
864 | } | 879 | } |
865 | 880 | ||
866 | void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) | 881 | void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) |