aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic/io_apic.c
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2011-01-04 19:38:52 -0500
committerIngo Molnar <mingo@elte.hu>2011-01-05 08:09:23 -0500
commitcb2ded37fd2e1039f96c8c892da024a8f033add5 (patch)
tree47dd8e3c19760b17130cedfe40b77299d7cd95af /arch/x86/kernel/apic/io_apic.c
parentbc030d6cb9532877c1c5a3f5e7123344fa24a285 (diff)
x86: Fix APIC ID sizing bug on larger systems, clean up MAX_APICS confusion
Found one x2apic pre-enabled system, x2apic_mode suddenly get corrupted after register some cpus, when compiled CONFIG_NR_CPUS=255 instead of 512. It turns out that generic_processor_info() ==> phyid_set(apicid, phys_cpu_present_map) causes the problem. phys_cpu_present_map is sized by MAX_APICS bits, and pre-enabled system some cpus have an apic id > 255. The variable after phys_cpu_present_map may get corrupted silently: ffffffff828e8420 B phys_cpu_present_map ffffffff828e8440 B apic_verbosity ffffffff828e8444 B local_apic_timer_c2_ok ffffffff828e8448 B disable_apic ffffffff828e844c B x2apic_mode ffffffff828e8450 B x2apic_disabled ffffffff828e8454 B num_processors ... Actually phys_cpu_present_map is referenced via apic id, instead index. We should use MAX_LOCAL_APIC instead MAX_APICS. For 64-bit it will be 32768 in all cases. BSS will increase by 4k bytes on 64-bit: text data bss dec filename 21696943 4193748 12787712 38678403 vmlinux.before 21696943 4193748 12791808 38682499 vmlinux.after No change on 32bit. Finally we can remove MAX_APCIS that was rather confusing. Signed-off-by: Yinghai Lu <yinghai@kernel.org> Cc: H. Peter Anvin <hpa@linux.intel.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> LKML-Reference: <4D23BD9C.3070102@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/apic/io_apic.c')
-rw-r--r--arch/x86/kernel/apic/io_apic.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 943d814ef8e4..2fc696e4d565 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -4109,7 +4109,8 @@ void __init pre_init_apic_IRQ0(void)
4109 4109
4110 printk(KERN_INFO "Early APIC setup for system timer0\n"); 4110 printk(KERN_INFO "Early APIC setup for system timer0\n");
4111#ifndef CONFIG_SMP 4111#ifndef CONFIG_SMP
4112 phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid); 4112 physid_set_mask_of_physid(boot_cpu_physical_apicid,
4113 &phys_cpu_present_map);
4113#endif 4114#endif
4114 /* Make sure the irq descriptor is set up */ 4115 /* Make sure the irq descriptor is set up */
4115 cfg = alloc_irq_and_cfg_at(0, 0); 4116 cfg = alloc_irq_and_cfg_at(0, 0);