From: mikep@csd.uu.se There has been a number of problem reports about local APIC interacting badly with ACPI on P4s due to the P4 local APIC force-enable change in 2.5.74, This patch reverts the 2.5.74 patch, so if the BIOS disables the local APIC on a P4, we don't enable it by default any more. The rescue the situation for those P4 systems where the local APIC _can_ be enabled safely, I've added two kernel parameters that can be used to override broken BIOSen: - "nolapic" prevents the kernel from enabling or using the local APIC. This is stronger than listing a machine in the DMI scan blacklist, since it also works for machines that boot with the local APIC already enabled. - "lapic" tells the kernel to force-enable the P4 local APIC if the BIOS disabled it. I haven't changed the logic for P6/K7 family processors, so we still force-enable those unless "nolapic" was passed to the kernel. The patch also includes a cleanup: the dont_use_local_apic_timer flag variable is not set any more since 2.5.74, so it's removed. 25-akpm/Documentation/kernel-parameters.txt | 4 +++ 25-akpm/arch/i386/kernel/apic.c | 34 ++++++++++++++++++++-------- 25-akpm/arch/i386/kernel/dmi_scan.c | 6 ++-- 3 files changed, 32 insertions(+), 12 deletions(-) diff -puN arch/i386/kernel/apic.c~local-apic-enable-fixes arch/i386/kernel/apic.c --- 25/arch/i386/kernel/apic.c~local-apic-enable-fixes Tue Jul 29 13:58:48 2003 +++ 25-akpm/arch/i386/kernel/apic.c Tue Jul 29 13:58:48 2003 @@ -594,7 +594,26 @@ static void apic_pm_activate(void) { } * Detect and enable local APICs on non-SMP boards. * Original code written by Keir Fraser. */ -int dont_enable_local_apic __initdata = 0; + +/* + * Knob to control our willingness to enable the local APIC. + */ +int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ + +static int __init lapic_disable(char *str) +{ + enable_local_apic = -1; + clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); + return 0; +} +__setup("nolapic", lapic_disable); + +static int __init lapic_enable(char *str) +{ + enable_local_apic = 1; + return 0; +} +__setup("lapic", lapic_enable); static int __init detect_init_APIC (void) { @@ -602,7 +621,7 @@ static int __init detect_init_APIC (void extern void get_cpu_vendor(struct cpuinfo_x86*); /* Disabled by DMI scan or kernel option? */ - if (dont_enable_local_apic) + if (enable_local_apic < 0) return -1; /* Workaround for us being called before identify_cpu(). */ @@ -616,7 +635,7 @@ static int __init detect_init_APIC (void goto no_apic; case X86_VENDOR_INTEL: if (boot_cpu_data.x86 == 6 || - boot_cpu_data.x86 == 15 || + (boot_cpu_data.x86 == 15 && (cpu_has_apic || enable_local_apic > 0)) || (boot_cpu_data.x86 == 5 && cpu_has_apic)) break; goto no_apic; @@ -897,14 +916,8 @@ int __init calibrate_APIC_clock(void) static unsigned int calibration_result; -int dont_use_local_apic_timer __initdata = 0; - void __init setup_boot_APIC_clock(void) { - /* Disabled by DMI scan or kernel option? */ - if (dont_use_local_apic_timer) - return; - printk("Using local APIC timer interrupts.\n"); using_apic_timer = 1; @@ -1121,6 +1134,9 @@ asmlinkage void smp_error_interrupt(void */ int __init APIC_init_uniprocessor (void) { + if (enable_local_apic < 0) + clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); + if (!smp_found_config && !cpu_has_apic) return -1; diff -puN arch/i386/kernel/dmi_scan.c~local-apic-enable-fixes arch/i386/kernel/dmi_scan.c --- 25/arch/i386/kernel/dmi_scan.c~local-apic-enable-fixes Tue Jul 29 13:58:48 2003 +++ 25-akpm/arch/i386/kernel/dmi_scan.c Tue Jul 29 13:58:48 2003 @@ -300,9 +300,9 @@ static __init int apm_is_horked(struct d static int __init local_apic_kills_bios(struct dmi_blacklist *d) { #ifdef CONFIG_X86_LOCAL_APIC - extern int dont_enable_local_apic; - if (!dont_enable_local_apic) { - dont_enable_local_apic = 1; + extern int enable_local_apic; + if (enable_local_apic == 0) { + enable_local_apic = -1; printk(KERN_WARNING "%s with broken BIOS detected. " "Refusing to enable the local APIC.\n", d->ident); diff -puN Documentation/kernel-parameters.txt~local-apic-enable-fixes Documentation/kernel-parameters.txt --- 25/Documentation/kernel-parameters.txt~local-apic-enable-fixes Tue Jul 29 13:58:48 2003 +++ 25-akpm/Documentation/kernel-parameters.txt Tue Jul 29 13:58:48 2003 @@ -436,6 +436,8 @@ running once the system is up. l2cr= [PPC] + lapic [IA-32,APIC] Enable the local APIC even if BIOS disabled it. + lasi= [HW,SCSI] PARISC LASI driver for the 53c700 chip Format: addr:,irq: @@ -625,6 +627,8 @@ running once the system is up. nointroute [IA-64] + nolapic [IA-32,APIC] Do not enable or use the local APIC. + nomce [IA-32] Machine Check Exception noresume [SWSUSP] Disables resume and restore original swap space. _