Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86: select x2apic ops in early apic probe only if x2apic mode is enabled

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>

authored by

Suresh Siddha and committed by
Ingo Molnar
ef1f87aa 9be1b56a

+18 -21
+1 -1
arch/x86/include/asm/apic.h
··· 146 146 return val; 147 147 } 148 148 149 - extern int x2apic; 149 + extern int x2apic, x2apic_phys; 150 150 extern void check_x2apic(void); 151 151 extern void enable_x2apic(void); 152 152 extern void enable_IR_x2apic(void);
+1 -8
arch/x86/kernel/apic/apic.c
··· 1265 1265 #ifdef CONFIG_X86_X2APIC 1266 1266 void check_x2apic(void) 1267 1267 { 1268 - int msr, msr2; 1269 - 1270 - if (!cpu_has_x2apic) 1271 - return; 1272 - 1273 - rdmsr(MSR_IA32_APICBASE, msr, msr2); 1274 - 1275 - if (msr & X2APIC_ENABLE) { 1268 + if (x2apic_enabled()) { 1276 1269 pr_info("x2apic enabled by BIOS, switching to x2apic ops\n"); 1277 1270 x2apic_preenabled = x2apic = 1; 1278 1271 }
+10 -3
arch/x86/kernel/apic/probe_64.c
··· 50 50 void __init default_setup_apic_routing(void) 51 51 { 52 52 #ifdef CONFIG_X86_X2APIC 53 - if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) { 54 - if (!intr_remapping_enabled) 55 - apic = &apic_flat; 53 + if (x2apic && (apic != &apic_x2apic_phys && 54 + #ifdef CONFIG_X86_UV 55 + apic != &apic_x2apic_uv_x && 56 + #endif 57 + apic != &apic_x2apic_cluster)) { 58 + if (x2apic_phys) 59 + apic = &apic_x2apic_phys; 60 + else 61 + apic = &apic_x2apic_cluster; 62 + printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); 56 63 } 57 64 #endif 58 65
+1 -4
arch/x86/kernel/apic/x2apic_cluster.c
··· 14 14 15 15 static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) 16 16 { 17 - if (cpu_has_x2apic) 18 - return 1; 19 - 20 - return 0; 17 + return x2apic_enabled(); 21 18 } 22 19 23 20 /* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */
+5 -5
arch/x86/kernel/apic/x2apic_phys.c
··· 10 10 #include <asm/apic.h> 11 11 #include <asm/ipi.h> 12 12 13 - static int x2apic_phys; 13 + int x2apic_phys; 14 14 15 15 static int set_x2apic_phys_mode(char *arg) 16 16 { ··· 21 21 22 22 static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) 23 23 { 24 - if (cpu_has_x2apic && x2apic_phys) 25 - return 1; 26 - 27 - return 0; 24 + if (x2apic_phys) 25 + return x2apic_enabled(); 26 + else 27 + return 0; 28 28 } 29 29 30 30 /* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */