diff options
author | Yinghai Lu <yinghai@kernel.org> | 2011-01-04 19:38:52 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-01-05 08:09:23 -0500 |
commit | cb2ded37fd2e1039f96c8c892da024a8f033add5 (patch) | |
tree | 47dd8e3c19760b17130cedfe40b77299d7cd95af /arch/x86/kernel/acpi | |
parent | bc030d6cb9532877c1c5a3f5e7123344fa24a285 (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/acpi')
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 7235e5fbdb6d..17c8090fabd4 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -915,13 +915,13 @@ static int __init acpi_parse_madt_lapic_entries(void) | |||
915 | acpi_register_lapic_address(acpi_lapic_addr); | 915 | acpi_register_lapic_address(acpi_lapic_addr); |
916 | 916 | ||
917 | count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, | 917 | count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, |
918 | acpi_parse_sapic, MAX_APICS); | 918 | acpi_parse_sapic, MAX_LOCAL_APIC); |
919 | 919 | ||
920 | if (!count) { | 920 | if (!count) { |
921 | x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC, | 921 | x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC, |
922 | acpi_parse_x2apic, MAX_APICS); | 922 | acpi_parse_x2apic, MAX_LOCAL_APIC); |
923 | count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, | 923 | count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, |
924 | acpi_parse_lapic, MAX_APICS); | 924 | acpi_parse_lapic, MAX_LOCAL_APIC); |
925 | } | 925 | } |
926 | if (!count && !x2count) { | 926 | if (!count && !x2count) { |
927 | printk(KERN_ERR PREFIX "No LAPIC entries present\n"); | 927 | printk(KERN_ERR PREFIX "No LAPIC entries present\n"); |