aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic/apic.c
diff options
context:
space:
mode:
authorCyrill Gorcunov <gorcunov@openvz.org>2009-06-07 08:48:40 -0400
committerIngo Molnar <mingo@elte.hu>2009-06-07 10:08:05 -0400
commit103428e57be323c3c5545db8ad12667099bc6005 (patch)
tree8f8275235b7ef7ff13bf3a2a7c9e13035ec61052 /arch/x86/kernel/apic/apic.c
parent3d58829b0510244596079c1d2f1762c53aef2e97 (diff)
x86, apic: Fix dummy apic read operation together with broken MP handling
Ingo Molnar reported that read_apic is buggy novadays: [ 0.000000] Using APIC driver default [ 0.000000] SMP: Allowing 1 CPUs, 0 hotplug CPUs [ 0.000000] Local APIC disabled by BIOS -- you can enable it with "lapic" [ 0.000000] APIC: disable apic facility [ 0.000000] ------------[ cut here ]------------ [ 0.000000] WARNING: at arch/x86/kernel/apic/apic.c:254 native_apic_read_dummy+0x2d/0x3b() [ 0.000000] Hardware name: HP OmniBook PC Indeed we still rely on apic->read operation for SMP compiled kernel. And instead of disfigure the SMP code with #ifdef we allow to call apic->read. To capture any unexpected results we check for apic->read being called for sane reason via WARN_ON_ONCE but(!) instead of OR we should use AND logical operation (thanks Yinghai for spotting the root of the problem). Along with that we could be have bad MP table and we are to fix it that way no SMP started and no complains about BIOS bug if apic was just disabled via command line. Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Cc: Yinghai Lu <yinghai@kernel.org> LKML-Reference: <20090607124840.GD4547@lenovo> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/apic/apic.c')
-rw-r--r--arch/x86/kernel/apic/apic.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index e82488d3f0ba..a4c9cf0bf70b 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -249,7 +249,7 @@ static void native_apic_write_dummy(u32 reg, u32 v)
249 249
250static u32 native_apic_read_dummy(u32 reg) 250static u32 native_apic_read_dummy(u32 reg)
251{ 251{
252 WARN_ON_ONCE((cpu_has_apic || !disable_apic)); 252 WARN_ON_ONCE((cpu_has_apic && !disable_apic));
253 return 0; 253 return 0;
254} 254}
255 255
@@ -1609,6 +1609,13 @@ void __init init_apic_mappings(void)
1609 new_apicid = read_apic_id(); 1609 new_apicid = read_apic_id();
1610 if (boot_cpu_physical_apicid != new_apicid) { 1610 if (boot_cpu_physical_apicid != new_apicid) {
1611 boot_cpu_physical_apicid = new_apicid; 1611 boot_cpu_physical_apicid = new_apicid;
1612 /*
1613 * yeah -- we lie about apic_version
1614 * in case if apic was disabled via boot option
1615 * but it's not a problem for SMP compiled kernel
1616 * since smp_sanity_check is prepared for such a case
1617 * and disable smp mode
1618 */
1612 apic_version[new_apicid] = 1619 apic_version[new_apicid] =
1613 GET_APIC_VERSION(apic_read(APIC_LVR)); 1620 GET_APIC_VERSION(apic_read(APIC_LVR));
1614 } 1621 }