x86: select x2apic ops in early apic probe only if x2apic mode is enabled
authorSuresh Siddha <suresh.b.siddha@intel.com>
Sat, 21 Feb 2009 22:23:21 +0000 (14:23 -0800)
committerIngo Molnar <mingo@elte.hu>
Sun, 22 Feb 2009 17:20:50 +0000 (18:20 +0100)
If BIOS hands over the control to OS in legacy xapic mode, select
legacy xapic related ops in the early apic probe and shift to x2apic
ops later in the boot sequence, only after enabling x2apic mode.

If BIOS hands over the control in x2apic mode, select x2apic related
ops in the early apic probe.

This fixes the early boot panic, where we were selecting x2apic ops,
while the cpu is still in legacy xapic mode.

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/include/asm/apic.h
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/probe_64.c
arch/x86/kernel/apic/x2apic_cluster.c
arch/x86/kernel/apic/x2apic_phys.c

index dce1bf696ccabbf883c27fd01327e1e37384de24..a6208dc746338fa1fd10810e29b1a4dd108998e9 100644 (file)
@@ -146,7 +146,7 @@ static inline u64 native_x2apic_icr_read(void)
        return val;
 }
 
-extern int x2apic;
+extern int x2apic, x2apic_phys;
 extern void check_x2apic(void);
 extern void enable_x2apic(void);
 extern void enable_IR_x2apic(void);
index c12823eb55b5974f7facdd040f33c741a8bdad77..47c2d12e5cf5116489e958f1ad763711c192a3e4 100644 (file)
@@ -1265,14 +1265,7 @@ void __cpuinit end_local_APIC_setup(void)
 #ifdef CONFIG_X86_X2APIC
 void check_x2apic(void)
 {
-       int msr, msr2;
-
-       if (!cpu_has_x2apic)
-               return;
-
-       rdmsr(MSR_IA32_APICBASE, msr, msr2);
-
-       if (msr & X2APIC_ENABLE) {
+       if (x2apic_enabled()) {
                pr_info("x2apic enabled by BIOS, switching to x2apic ops\n");
                x2apic_preenabled = x2apic = 1;
        }
index 70935dd904db41e59b151fda0a912fb68fee11b0..e7c163661c773e058b4e1a4a75c20588c59bc39c 100644 (file)
@@ -50,9 +50,16 @@ static struct apic *apic_probe[] __initdata = {
 void __init default_setup_apic_routing(void)
 {
 #ifdef CONFIG_X86_X2APIC
-       if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) {
-               if (!intr_remapping_enabled)
-                       apic = &apic_flat;
+       if (x2apic && (apic != &apic_x2apic_phys &&
+#ifdef CONFIG_X86_UV
+                      apic != &apic_x2apic_uv_x &&
+#endif
+                      apic != &apic_x2apic_cluster)) {
+               if (x2apic_phys)
+                       apic = &apic_x2apic_phys;
+               else
+                       apic = &apic_x2apic_cluster;
+               printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
        }
 #endif
 
index 4e39d9ad4d52a609a84254a0f5d0517d06935205..354b9c45601d50c5f7a65156a24d764068b42572 100644 (file)
@@ -14,10 +14,7 @@ DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid);
 
 static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
-       if (cpu_has_x2apic)
-               return 1;
-
-       return 0;
+       return x2apic_enabled();
 }
 
 /* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
index d2d52eb9f7eaf738a6c47f3f08bb9adcc5167065..5bcb174409bca82a12141aae908b62aaf82e12e7 100644 (file)
@@ -10,7 +10,7 @@
 #include <asm/apic.h>
 #include <asm/ipi.h>
 
-static int x2apic_phys;
+int x2apic_phys;
 
 static int set_x2apic_phys_mode(char *arg)
 {
@@ -21,10 +21,10 @@ early_param("x2apic_phys", set_x2apic_phys_mode);
 
 static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
-       if (cpu_has_x2apic && x2apic_phys)
-               return 1;
-
-       return 0;
+       if (x2apic_phys)
+               return x2apic_enabled();
+       else
+               return 0;
 }
 
 /* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */