diff options
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
| -rw-r--r-- | arch/x86/kernel/cpu/common.c | 41 | 
1 files changed, 27 insertions, 14 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 77848d9fca6..6b26d4deada 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -13,6 +13,7 @@  #include <linux/io.h>  #include <asm/stackprotector.h> +#include <asm/perf_counter.h>  #include <asm/mmu_context.h>  #include <asm/hypervisor.h>  #include <asm/processor.h> @@ -107,7 +108,7 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {  	/* data */  	[GDT_ENTRY_APMBIOS_BASE+2]	= { { { 0x0000ffff, 0x00409200 } } }, -	[GDT_ENTRY_ESPFIX_SS]		= { { { 0x00000000, 0x00c09200 } } }, +	[GDT_ENTRY_ESPFIX_SS]		= { { { 0x0000ffff, 0x00cf9200 } } },  	[GDT_ENTRY_PERCPU]		= { { { 0x0000ffff, 0x00cf9200 } } },  	GDT_STACK_CANARY_INIT  #endif @@ -299,7 +300,8 @@ static const char *__cpuinit table_lookup_model(struct cpuinfo_x86 *c)  	return NULL;		/* Not found */  } -__u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata; +__u32 cpu_caps_cleared[NCAPINTS] __cpuinitdata; +__u32 cpu_caps_set[NCAPINTS] __cpuinitdata;  void load_percpu_segment(int cpu)  { @@ -485,7 +487,6 @@ out:  static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)  {  	char *v = c->x86_vendor_id; -	static int printed;  	int i;  	for (i = 0; i < X86_VENDOR_NUM; i++) { @@ -502,13 +503,9 @@ static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)  		}  	} -	if (!printed) { -		printed++; -		printk(KERN_ERR -		    "CPU: vendor_id '%s' unknown, using generic init.\n", v); - -		printk(KERN_ERR "CPU: Your system may be unstable.\n"); -	} +	printk_once(KERN_ERR +			"CPU: vendor_id '%s' unknown, using generic init.\n" \ +			"CPU: Your system may be unstable.\n", v);  	c->x86_vendor = X86_VENDOR_UNKNOWN;  	this_cpu = &default_cpu; @@ -768,6 +765,12 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)  	if (this_cpu->c_identify)  		this_cpu->c_identify(c); +	/* Clear/Set all flags overriden by options, after probe */ +	for (i = 0; i < NCAPINTS; i++) { +		c->x86_capability[i] &= ~cpu_caps_cleared[i]; +		c->x86_capability[i] |= cpu_caps_set[i]; +	} +  #ifdef CONFIG_X86_64  	c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);  #endif @@ -813,6 +816,16 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)  #endif  	init_hypervisor(c); + +	/* +	 * Clear/Set all flags overriden by options, need do it +	 * before following smp all cpus cap AND. +	 */ +	for (i = 0; i < NCAPINTS; i++) { +		c->x86_capability[i] &= ~cpu_caps_cleared[i]; +		c->x86_capability[i] |= cpu_caps_set[i]; +	} +  	/*  	 * On SMP, boot_cpu_data holds the common feature set between  	 * all CPUs; so make sure that we indicate which features are @@ -825,10 +838,6 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)  			boot_cpu_data.x86_capability[i] &= c->x86_capability[i];  	} -	/* Clear all flags overriden by options */ -	for (i = 0; i < NCAPINTS; i++) -		c->x86_capability[i] &= ~cleared_cpu_caps[i]; -  #ifdef CONFIG_X86_MCE  	/* Init Machine Check Exception if available. */  	mcheck_init(c); @@ -839,6 +848,9 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)  #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64)  	numa_add_cpu(smp_processor_id());  #endif + +	/* Cap the iomem address space to what is addressable on all CPUs */ +	iomem_resource.end &= (1ULL << c->x86_phys_bits) - 1;  }  #ifdef CONFIG_X86_64 @@ -861,6 +873,7 @@ void __init identify_boot_cpu(void)  #else  	vgetcpu_set_mode();  #endif +	init_hw_perf_counters();  }  void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c)  |