diff options
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index c1caefc82e62..b0517aa2bd3b 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -114,6 +114,13 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { | |||
114 | } }; | 114 | } }; |
115 | EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); | 115 | EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); |
116 | 116 | ||
117 | static int __init x86_xsave_setup(char *s) | ||
118 | { | ||
119 | setup_clear_cpu_cap(X86_FEATURE_XSAVE); | ||
120 | return 1; | ||
121 | } | ||
122 | __setup("noxsave", x86_xsave_setup); | ||
123 | |||
117 | #ifdef CONFIG_X86_32 | 124 | #ifdef CONFIG_X86_32 |
118 | static int cachesize_override __cpuinitdata = -1; | 125 | static int cachesize_override __cpuinitdata = -1; |
119 | static int disable_x86_serial_nr __cpuinitdata = 1; | 126 | static int disable_x86_serial_nr __cpuinitdata = 1; |
@@ -292,7 +299,8 @@ static const char *__cpuinit table_lookup_model(struct cpuinfo_x86 *c) | |||
292 | return NULL; /* Not found */ | 299 | return NULL; /* Not found */ |
293 | } | 300 | } |
294 | 301 | ||
295 | __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata; | 302 | __u32 cpu_caps_cleared[NCAPINTS] __cpuinitdata; |
303 | __u32 cpu_caps_set[NCAPINTS] __cpuinitdata; | ||
296 | 304 | ||
297 | void load_percpu_segment(int cpu) | 305 | void load_percpu_segment(int cpu) |
298 | { | 306 | { |
@@ -761,6 +769,12 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
761 | if (this_cpu->c_identify) | 769 | if (this_cpu->c_identify) |
762 | this_cpu->c_identify(c); | 770 | this_cpu->c_identify(c); |
763 | 771 | ||
772 | /* Clear/Set all flags overriden by options, after probe */ | ||
773 | for (i = 0; i < NCAPINTS; i++) { | ||
774 | c->x86_capability[i] &= ~cpu_caps_cleared[i]; | ||
775 | c->x86_capability[i] |= cpu_caps_set[i]; | ||
776 | } | ||
777 | |||
764 | #ifdef CONFIG_X86_64 | 778 | #ifdef CONFIG_X86_64 |
765 | c->apicid = apic->phys_pkg_id(c->initial_apicid, 0); | 779 | c->apicid = apic->phys_pkg_id(c->initial_apicid, 0); |
766 | #endif | 780 | #endif |
@@ -806,6 +820,16 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
806 | #endif | 820 | #endif |
807 | 821 | ||
808 | init_hypervisor(c); | 822 | init_hypervisor(c); |
823 | |||
824 | /* | ||
825 | * Clear/Set all flags overriden by options, need do it | ||
826 | * before following smp all cpus cap AND. | ||
827 | */ | ||
828 | for (i = 0; i < NCAPINTS; i++) { | ||
829 | c->x86_capability[i] &= ~cpu_caps_cleared[i]; | ||
830 | c->x86_capability[i] |= cpu_caps_set[i]; | ||
831 | } | ||
832 | |||
809 | /* | 833 | /* |
810 | * On SMP, boot_cpu_data holds the common feature set between | 834 | * On SMP, boot_cpu_data holds the common feature set between |
811 | * all CPUs; so make sure that we indicate which features are | 835 | * all CPUs; so make sure that we indicate which features are |
@@ -818,10 +842,6 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
818 | boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; | 842 | boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; |
819 | } | 843 | } |
820 | 844 | ||
821 | /* Clear all flags overriden by options */ | ||
822 | for (i = 0; i < NCAPINTS; i++) | ||
823 | c->x86_capability[i] &= ~cleared_cpu_caps[i]; | ||
824 | |||
825 | #ifdef CONFIG_X86_MCE | 845 | #ifdef CONFIG_X86_MCE |
826 | /* Init Machine Check Exception if available. */ | 846 | /* Init Machine Check Exception if available. */ |
827 | mcheck_init(c); | 847 | mcheck_init(c); |