Merge branches 'x86-detect-hyper-for-linus', 'x86-fpu-for-linus', 'x86-kexec-for...
[linux-2.6.git] / arch / x86 / kernel / apic / apic.c
index b9338b8..b24be38 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/syscore_ops.h>
 #include <linux/delay.h>
 #include <linux/timex.h>
+#include <linux/i8253.h>
 #include <linux/dmar.h>
 #include <linux/init.h>
 #include <linux/cpu.h>
@@ -39,7 +40,6 @@
 #include <asm/pgalloc.h>
 #include <asm/atomic.h>
 #include <asm/mpspec.h>
-#include <asm/i8253.h>
 #include <asm/i8259.h>
 #include <asm/proto.h>
 #include <asm/apic.h>
@@ -48,6 +48,7 @@
 #include <asm/hpet.h>
 #include <asm/idle.h>
 #include <asm/mtrr.h>
+#include <asm/time.h>
 #include <asm/smp.h>
 #include <asm/mce.h>
 #include <asm/tsc.h>
@@ -1429,7 +1430,7 @@ void enable_x2apic(void)
        rdmsr(MSR_IA32_APICBASE, msr, msr2);
        if (!(msr & X2APIC_ENABLE)) {
                printk_once(KERN_INFO "Enabling x2apic\n");
-               wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0);
+               wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, msr2);
        }
 }
 #endif /* CONFIG_X86_X2APIC */
@@ -1943,10 +1944,28 @@ void disconnect_bsp_APIC(int virt_wire_setup)
 
 void __cpuinit generic_processor_info(int apicid, int version)
 {
-       int cpu;
+       int cpu, max = nr_cpu_ids;
+       bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid,
+                               phys_cpu_present_map);
+
+       /*
+        * If boot cpu has not been detected yet, then only allow upto
+        * nr_cpu_ids - 1 processors and keep one slot free for boot cpu
+        */
+       if (!boot_cpu_detected && num_processors >= nr_cpu_ids - 1 &&
+           apicid != boot_cpu_physical_apicid) {
+               int thiscpu = max + disabled_cpus - 1;
+
+               pr_warning(
+                       "ACPI: NR_CPUS/possible_cpus limit of %i almost"
+                       " reached. Keeping one slot for boot cpu."
+                       "  Processor %d/0x%x ignored.\n", max, thiscpu, apicid);
+
+               disabled_cpus++;
+               return;
+       }
 
        if (num_processors >= nr_cpu_ids) {
-               int max = nr_cpu_ids;
                int thiscpu = max + disabled_cpus;
 
                pr_warning(